JVM之G1垃圾回收器

JVM之G1垃圾回收器

 

G1垃圾收集器采用的是区域化、分布式的垃圾回收器。堆被划分成 许多个连续的区域(region)。每个区域大小相等,在1M~32M之间。JVM最多支持2000个区域,可推算G1能支持的最大内存为2000*32M=62.5G。区域(region)的大小在JVM初始化的时候决定,也可以用-XX:G1HeapReginSize设置。

 

虽然在G1收集器里面将整个内存区域都混合在了一起,但是其本身依然也是在小范围内要进行年轻代与老年代的区分,也就是说依然会采用不同的GC方式来处理不同的区域。

 

 

 

内存占用

 

如果从 ParallelOldGC 或者 CMS收集器迁移到 G1, 您可能会看到JVM进程占用更多的内存(a larger JVM process size). 这在很大程度上与 “accounting” 数据结构有关, 如 Remembered Sets 和 Collection Sets.

 

Remembered Sets

简称 RSets, 跟踪指向某个heap区内的对象引用. 堆内存中的每个区都有一个 RSet. RSet 使heap区能并行独立地进行垃圾集合. RSets的总体影响小于5%。


Collection Sets

简称 CSets, 收集集合, 在一次GC中将执行垃圾回收的heap区. GC时在CSet中的所有存活数据(live data)都会被转移(复制/移动). 集合中的heap区可以是 Eden, survivor, 和/或 old generation. CSets所占用的JVM内存小于1%。

 

 

 

适用场景

 

G1的首要目标是为需要大量内存的系统提供一个保证GC低延迟的解决方案. 也就是说堆内存在6GB及以上,稳定和可预测的暂停时间小于0.5秒。

 

如果应用程序具有如下的一个或多个特征,那么将垃圾收集器从CMS或ParallelOldGC切换到G1将会大大提升性能。

 

  • Full GC 次数太频繁或者消耗时间太长
  • 对象分配的频率或代数提升(promotion)显著变化
  • 受够了太长的垃圾回收或内存整理时间(超过0.5~1秒)

注意: 如果正在使用CMS或ParallelOldGC,而应用程序的垃圾收集停顿时间并不长,那么继续使用现在的垃圾收集器是个好主意. 使用最新的JDK时并不要求切换到G1收集器。

 

 

 

年轻代垃圾回收

 

  • 堆一整块内存空间,被分为多个heap区(regions)
  • 年轻代内存由一组不连续的heap区组成. 这使得在需要时很容易进行容量调整
  • 年轻代的垃圾收集,或者叫 young GCs, 会有 stop the world 事件. 在操作时所有的应用程序线程都会被暂停(stopped)
  • 年轻代 GC 通过多线程并行进行
  • 存活的对象被拷贝到新的 survivor 区或者老年代

 

垃圾回收前

 

垃圾回收后


 

 

 

 

老年代垃圾回收

 

       和 CMS 收集器相似, G1 收集器也被设计为用来对老年代的对象进行低延迟(low pause)的垃圾收集. 下表描述了G1收集器在老年代进行垃圾回收的各个阶段

 



 

 

 

 

 

 

 

 

 

老年代垃圾回收的几个关键点

 

1. 并发标记清理阶段(Concurrent Marking Phase)
  • 活跃度信息在程序运行的时候被并行计算出来
  • 活跃度(liveness)信息标识出哪些区域在转移暂停期间最适合回收.
  • 不像CMS一样有清理阶段(sweeping phase).

2. 再次标记阶段(Remark Phase)

  • 使用的 Snapshot-at-the-Beginning (SATB, 开始快照) 算法比起 CMS所用的算法要快得多.
  • 完全空的区域直接被回收.

3. 拷贝/清理阶段(Copying/Cleanup Phase)

  • 年轻代与老年代同时进行回收.
  • 老年代的选择基于其活跃度(liveness).

 

相关参数



 
 例子:

 java -Xmx10m -Xms10m -XX:+UseG1GC -XX:+PrintGCDetails TestDemo

 

 

 

总结

 

G1处理和传统的垃圾收集策略是不同的,关键的因素是它将所有的内存进行了子区域的划分。

 

 

 

CMS和G1的比较

 

1. CMS用标记——清除算法,G1用标记——整理算法。CMS容易出现内存碎片,G1不会,所以CMS回收完垃圾后要压缩内存,可以配置。不然可能因为碎片太多,大片内存不够导致Full GC,还有可能导致切换到备用的老年代垃圾回收器Serial Old。

 

2. CMS只能回收老年代,G1可以回收整个堆,因为G1有分代回收的配置。

 

3. CMS使用并发回收,所以不会导致用户停顿,但是对CPU非常敏感,所以回收时会占用一部分线程,使应用变慢,总吞吐量降低。G1用了并行收集和并发收集,发挥了多个CPU的优势,可以非常精确地控制停顿时间,而且不牺牲吞吐量。

 

 

 

猜你喜欢

转载自youyu4.iteye.com/blog/2354274