剖析G1(Garbage First)

Java从JDK7U9开始支持G1(正式发布),所以,如果要使用G1的话,你的Java版本应该是JDK7U9或者更新的版本。不过,强烈建议JDK8才使用G1,而且最好是JDK8的最新版本,因为在JDK7~JDK8最新版本迭代过程中,Java针对G1垃圾回收期做了大量的优化工作。

G1垃圾回收器是为多处理器大内存的服务器而设计的,它根据运行JVM过程中构建的停顿预测模型(Pause Prediction Model)计算出来的历史数据来预测本次收集需要选择的Region数量,然后尽可能(不是绝对)满足GC的停顿时间,G1期望能让JVM的GC成为一件简单的事情。G1旨在延迟性和吞吐量之间取得最佳的平衡,它尝试解决有如下问题的Java应用:

  1. 堆大小能达到几十G甚至更大,超过50%的堆空间都是存活的对象;
  2. 对象分配和晋升的速度随着时间的推移有很大的影响;
  3. 堆上严重的碎片化问题;
  4. 可预测的停顿时间,避免长时间的停顿。

  • 开启G1

介绍G1之前先简单的说一下如何开启G1,在JDK9之前,JDK7和JDK8默认都是ParallelGC垃圾回收。到了JDK9,G1才是默认的垃圾回收器。所以如果JDK7或者JDK8需要使用G1的话,需要通过参数(-XX:+UseG1GC)显示执行垃圾回收器。而JDK9以后的版本,不需要任何JVM参数,默认就是G1垃圾回收模式,显示指定G1运行一个Demo程序如下:

java -Xmx1g -Xms1g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar demo.jar
  • G1堆

G1的堆结构,是Java发展这么多年,第一次发生这么大的变化。以前,无论是使用SerialGC,ParallelGC,还是CMS,堆的年轻代和老年代都是连续的,且堆结构图都是如下所示:
以前GC的堆

而G1的堆是基于Region设计的,事实上,这些Region本质上就是Eden、Survivor和Old,而且同类型的Region可以不连续。如下图所示:
G1 Heap Allocation

图片中不同的颜色表示不同的Region,Region被设计为在停止所有其他应用程序线程的情况下并行收集,即是STW的。

另外,除了图中3种常见的Region类型,还有第四种特殊的Region,即:Humongous,它是特殊的老年代Region。这种Region被设计用来保存超过Region的50%空间的对象,它们存储在一系列连续的Region中。通常来说,超大对象只会在最终标记结束后的清理阶段(cleanup)才会被回收,或者发生FullGC时。但是在JDK8U40的时候,JDK更新了一些收集超大对象的特性,以至于在YGC的时候,G1也能回收那些没有任何引用指向的超大对象,可以通过参数**-XX:+G1ReclaimDeadHumongousObjectsAtYoungGC控制,这个参数后来被更名为-XX:+G1EagerReclaimHumongousObjects**,并且可以通过参数**-XX:+G1TraceEagerReclaimHumongousObjects**跟踪并输出超大对象回收相关信息。

超大对象的分配可能导致过早的发生垃圾回收,每一个超大对象分配时,G1会检查初始堆占用阈值**-XX:InitiatingHeapOccupancyPercent**,如果占用比例超过了阈值,那么就会触发全局并发标记。如果超大对象的分配导致连续发生全局并发标记,那么请考虑适当增加参数 -XX:G1HeapRegionSize 的值,这样一来,之前的超大对象就不再是超大对象,而是采用常规的分配方式的普通对象。另外,超大对象的分配还会导致老年代碎片化,需要注意。

超大对象从来不会被移动(但是可以被清理),即使发生的是FullGC。这可能会导致过早的FullGC或者一些意料之外的OOM,而事实上还有很多可用堆空间。

JVM启动的时候就会自动设置Region大小,当然,你也可以自己指定Region的大小(例如-XX:G1HeapRegionSize=4m)。Region数量最多不会超过2048个,每个Region的大小在1~32M之间,且必须是2的N次方。这就意味着,如果堆内存少于2048M(2G),那么Region数量就会少于2048个。

以前GC的垃圾收集主要分为年轻代的垃

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值