doc: 阅读G1垃圾收集器文档

This commit is contained in:
asahi
2025-12-06 23:38:53 +08:00
parent db552403d2
commit 00e751439e

View File

@@ -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%;">