JVM G1源码分析和调优

JVM G1源码分析和调优

作者:彭成寒 编著

出版社:机械工业

出版年:2019年3月

ISBN:9787111621973

所属分类:网络科技

书刊介绍

《JVM G1源码分析和调优》内容简介

G1是目前最成熟的垃圾回收器,已经广泛应用在众多公司的生产环境中。我们知道,CMS作为使用最为广泛的垃圾回收器,也有令人头疼的问题,即如何对其众多的参数进行正确的设置。G1的目标就是替代CMS,所以在设计之初就希望降低程序员的负担,减少人工的介入。但这并不意味着我们完全不需要了解G1的原理和参数调优。笔者在实际工作中遇到过一些因参数设置不正确而导致GC停顿时间过长的问题。但要正确设置参数并不容易,这里涉及两个方面:第一,需要对G1的原理熟悉,只有熟悉G1的原理才知道调优的方向;第二,能分析和解读G1运行的日志信息,根据日志信息找到G1运行过程中的异常信息,并推断哪些参数可以解决这些异常。本书尝试从G1的原理出发,系统地介绍新生代回收、混合回收、Full GC、并发标记、Refine线程等内容;同时依托于jdk8u的源代码介绍Hotspot如何实现G1,通过对源代码的分析来了解G1提供了哪些参数、这些参数的具体意义;最后本书还设计了一些示例代码,给出了G1在运行这些示例代码时的日志,通过日志分析来尝试调整参数并达到性能优化,还分析了参数调整可能带来的负面影响。
彭成寒编著。

作品目录

前言
第1章:垃圾回收概述
1.1、Java发展概述
1.2、本书常见术语
1.3、回收算法概述
1.4、JVM垃圾回收器概述
第2章:G1的基本概念
2.1、分区
2.2、G1停顿预测模型
2.3、卡表和位图
2.4、对象头
2.5、内存分配和管理
2.6、线程
2.7、日志解读
2.8、参数介绍和调优
第3章:G1的对象分配
3.1、对象分配概述
3.2、快速分配
3.3、慢速分配
3.4、G1垃圾回收的时机
3.5、参数介绍和调优
第4章:G1的Refine线程
4.1、记忆集
4.2、Refine线程的功能及原理
4.3、Refinement
Zone
4.4、RSet涉及的写屏障
4.5、日志解读
4.6、参数介绍和调优
第5章:新生代回收
5.1、YGC算法概述
5.2、YGC代码分析
5.3、YGC算法演示
5.4、日志解读
5.5、参数介绍和调优
第6章:混合回收
6.1、并发标记算法详解
6.2、并发标记算法的难点
6.3、G1中混合回收的步骤
6.4、混合回收中并发标记处理的线程
6.5、并发标记算法演示
6.6、GC活动图
6.7、日志解读
6.8、参数优化
第7章:Full
GC
7.1、Evac失败
7.2、串行FGC
7.3、并行FGC
7.4、日志解读
7.5、参数介绍和调优
第8章:G1中的引用处理
8.1、引用概述
8.2、可回收对象发现
8.3、在GC时的处理发现列表
8.4、重新激活可达的引用
8.5、日志解读
8.6、参数介绍和调优
第9章:G1的新特性:字符串去重
9.1、字符串去重概述
9.2、日志解读
9.3、参数介绍和调优
9.4、字符串去重和String.intern的区别
9.5、String.intern中的实现
第10章:线程中的安全点
10.1、安全点的基本概念
10.2、G1并发线程进入安全点
10.3、解释线程进入安全点
10.4、编译线程进入安全点
10.5、正在执行本地代码的线程进入安全点
10.6、安全点小结
10.7、日志分析
10.8、参数介绍和调优
第11章:垃圾回收器的选择
11.1、如何衡量垃圾回收器
11.2、G1调优的方向
第12章:新一代垃圾回收器
12.1、Shenandoah
12.2、ZGC
附录A
编译调试JVM
附录B
本地内存跟踪
附录C
阅读JVM需要了解的C++知识

热门书摘

并发标记开始之后,如果有新的对象分配

MaxGCPauseMillis

为什么以字为单位?原因是JVM中对象会对齐,所以不需要按字节移动

位图(bitmap)

用一个位来描述一个字

一个字为32位

(32KB×32=1M)

位图不再描述一个字,而是一个区域

有一个参数可以控制对象最小对齐的大小,默认是8字节,实际上Java在JVM中还有一些附加信息,所以对齐后最小的Java对象是16字节

1MB的内存只需要2KB的额外空间就能描述引用关系

结构分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)

32位

线程是程序执行的基本单元

垃圾回收中最重要的根

Mutator

无论快速分配还是慢速分配,都应该在STW之外调用,即都应该尽量避免使用全局锁

JVM堆中分配一个固定大小的内存区域并将其作为线程的私有缓冲区

TLAB空间本身在分配的时候还是需要锁的

一个分区可能有多个TLAB块

对于对象,扫描之后可以直接跳过对象的长度,对于空白的地方只能一个字一个字地扫描,这会非常慢

外部显式地调用回收的方法,如在Java代码中调用system.gc()进入回收

G1中还引入了新的Refine线程用于处理这种引用关系

用一个RSet记录从非收集部分指向收集部分的指针的集合

Point Out

但是每一次YGC都是收集所有的新生代分区

对于YGC来说整个新生代分区就是CSet

RSet

PSS

收集老生代可能会花费更多的时间。所以涉及老生代的混合收集算法也不同于新生代回收算法,最明显的是引入并发标记,这里的并发标记指的是标记工作线程可以和Mutator同时运行,当然并发标记引入了复杂度

Mutator

并发标记的难点,一边标记垃圾对象,一边还在生成垃圾对象

Bottom表示分区的底部

如图6-3和图6-4所示

根对象

STW

Linux中使用的编译器是GCC,调试器是GDB

Mercurial(hg)

相关推荐

微信二维码