doc: 阅读G1垃圾收集器文档
This commit is contained in:
@@ -49,6 +49,9 @@
|
||||
- [Parallel Old](#parallel-old)
|
||||
- [CMS收集器](#cms收集器)
|
||||
- [CMS缺陷](#cms缺陷)
|
||||
- [G1垃圾收集器](#g1垃圾收集器)
|
||||
- [G1垃圾收集器内存布局](#g1垃圾收集器内存布局)
|
||||
- [Remembered Set](#remembered-set)
|
||||
|
||||
|
||||
# 深入理解java虚拟机
|
||||
@@ -419,5 +422,45 @@ CMS虽然在垃圾收集时能够做到停顿时间较短,但是其仍然存
|
||||
- 为了解决内存碎片问题,CMS提供了`-XX:+UseCMSCompactAtFullCollection`开关参数(默认是开启的),用于在CMS进行full gc时开启内存碎片的合并过程
|
||||
- 但是,每次full gc都进行内存碎片合并会导致等待时间过长,故而引入了另一个参数`-XX:CMSFullGCsBeforeCompaction`,该参数用于限制执行多少次不压缩的full gc后,再执行一次带压缩的(默认为0,代表每次进入fullgc后都进行碎片整理)
|
||||
|
||||
#### G1垃圾收集器
|
||||
G1是一项面对服务端应用的垃圾收集器,和其他垃圾收集器相比,G1具备如下特点:
|
||||
- `并行和并发`:
|
||||
- G1能够充分利用多cpu、多核环境下的硬件优势,利用多个cpu/cpu核心来缩短STW停顿时间
|
||||
- 在部分GC动作中,其他垃圾收集器都需要暂停用户线程的执行,而G1垃圾收集器则是在这些GC动作中仍然允许用户线程的同时执行
|
||||
- `分代垃圾收集`:和其他垃圾收集器一样,G1中也保留了分代的概念。但是,G1并不需要其他垃圾收集器的配合就能够独立管理整个GC堆
|
||||
- `空间整合`:和CMS的`标记-清理`算法不同,G1在整体上采用了`标记-整理`算法实现垃圾收集;而从局部(两个Region)上看,G1采用了复制算法。不管从整体还是局部上看,G1都不会产生内存碎片
|
||||
- `可预测的停顿`:G1相比于CMS的一大优势是G1造成的停顿可预测。G1和CMS都关注在垃圾回收中降低停顿,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者指明`在一个时间为M的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒`。
|
||||
|
||||
##### G1垃圾收集器内存布局
|
||||
在G1之前,其他的垃圾收集器在进行收集时都是只关注新生代或老年代对象,但G1则并非这样。在使用G1垃圾收集器时,java堆的内存布局和使用其他垃圾收集器有较大区别。
|
||||
|
||||
在使用G1垃圾收集器时,其将整个java堆划分为多个大小相等的独立区域(Region),虽然仍然保留有新生代和老年代的概念,但新生代和老年代并非在物理上是隔离的,它们都是一部分(并不需要连续)Region的集合。
|
||||
|
||||
G1之所以能够建立可预测的停顿模型,是因为其可以避免在整个java堆中进行全区域的垃圾收集。`G1会跟踪各个Region中垃圾堆积的价值大小(回收所获取的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的垃圾回收时间,优先回收价值最大的Region`。(这即是G1垃圾收集器的名称由来,即Garbage-First)。
|
||||
|
||||
`上述将内存空间划分为Region,以及有优先级的区域回收方式,能够保证G1垃圾收集器在有限的时间内以尽可能高的效率进行垃圾回收`。
|
||||
|
||||
##### Remembered Set
|
||||
即使将内存区域划分为多个Region,但是Region中的对象仍然会跨Region相互引用。故而,在进行可达性分析时,如果不做特殊处理,在分析某个Region中的对象存活与否时,仍然需要扫描整个堆内存空间。
|
||||
> 在使用其他垃圾收集器时,即使不对内存进行Region划分,在新生代和老年代之间也会存在相互引用。如果不做特殊处理,在分析新生代对象时,也必须扫描老年代。这将会极大的影响GC效率
|
||||
|
||||
G1收集器中Region之间的对象引用以及其他收集器中新生代和老年代之间的对象引用,虚拟机都是通过Remembered Set来避免整个堆的扫描的。`G1中,每个Region都有一个与之对应的Remembered Set,虚拟机发现程序在对reference类型的数据进行写操作时,会产生一个Write Barrier暂时中断写操作,检查Reference引用的对象是否处于不同的Region中,如果是,则将相关引用信息记录到被引用对象所属Region的Remembered Set中。`在进行内存回收时,在GC根节点枚举范围中加入Remembered Set即可保证不对全堆扫描也不会有遗漏。
|
||||
|
||||
若不计算维护Remembered Set的操作,G1垃圾收集器的运作可以分为如下步骤:
|
||||
- 初始标记:
|
||||
- 初始标记会记录GC Roots能直接关联到的对象
|
||||
- 其会修改TAMS,令下一阶段用户线程并发运行时,能在Region中创建新对象
|
||||
- 初始标记阶段需要STW,暂停用户线程
|
||||
- 并发标记
|
||||
- 对堆中对象进行可达性分析,找出存活对象
|
||||
- 该阶段耗时较长,但是可以和用户线程并发执行
|
||||
- 最终标记
|
||||
- 修正在并发标记期间因用户线程运行而导致的标记变动
|
||||
- 该阶段需要STW,暂停用户线程,但是可以并行执行
|
||||
- 筛选回收
|
||||
- 在筛选回收期间,会对各个Region的回收价值和成本进行排序,根据用户期望的GC停顿时间来制定回收计划
|
||||
- 在筛选回收阶段,也是会暂停用户线程的
|
||||
|
||||
<img src="https://ask.qcloudimg.com/http-save/5427637/ouqa71pbc7.jpeg" style="width: 100%;">
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user