JVM G1垃圾回收算法简要介绍
G1的特点
- 能够像CMS垃圾回收算法一样并发操作应用线程(潜台词:多核)
- 无需太长时间即可压缩空闲内存空间(潜台词:不会引起太多的GC停顿时间)
- 尽可能地让GC时长可控
- 不希望牺牲过多的吞吐量
- 不希望因此耗费大量更多的Heap空间
G1的优势
G1作为CMS的长期替代品,有若干点优势:
- G1是一个压缩收集器,提供足够强的压缩来完全避免狭小的内存分配
- 依赖Regions概念,大大简化收集器逻辑,大部分情况下规避潜在的内存碎片问题
- 比CMS的GC停顿时长更加可预测,并允许用户指定停顿时长
G1的收集步骤
Phase 1: Concurrent Global Marking. 并发扫描一遍之后,G1知道了哪些Region里大部分是空的(即大部分是可回收的对象),G1把收集和压缩操作集中于此,因此得名Garbage First.
Phase 2: Evacuation. 并发地将一个或多个Region的资源拷贝至新的Region,压缩内存、拷贝、释放已拷贝完成的Region. 与此相比,CMS没有压缩内存(去除碎片)这一步,ParallelOld垃圾收集只进行全堆压缩.
细节:G1会估算Region的回收时间,以计算在用户指定时间内可回收多少(量力而行),因此G1不是『实时』收集器 :)
G1的建议使用场景
拥有较大Heap空间(6GB及以上)、低停顿时长(0.5ms以内)要求的应用。
现在使用ParallelGC或CMS的应用,如果存在以下问题,可以考虑切换至G1:
- Full GC过于频繁、停顿时间过长的应用
- 对象分配比例经常发生剧变的应用
- 回收或压缩时间太长的应用(高于0.5s到1s)
如果使用ParallelGC或CMS没有发现以上现象,可以不必急于切换到G1,新版JVM仍然支持旧的垃圾回收算法。
G1的注意事项
若从ParallelOldGC或CMS切换至G1,很可能会发现JVM运行内存变大了。这很大程度上要归因于 用于审计的两个数据结构『Remembered Sets』和『Collection Sets』
- 『Remembered Sets』每个Region都有一个,用于记录该Region中的对象引用,给G1提供并行独立收集各Region内存的可能性,它带来的负面影响不超5%
- 『Collection Sets』记录被收集的Region,它内部的所有数据会被收集干净,它带来的负面影响不超1%