探索G1垃圾回收器 (2)

探索G1垃圾回收器

 

 

老年代具体又是怎么进行垃圾回收的呢

这个过程说起来可能稍微复杂了一点,但是它和CMS的垃圾回收过程其实是类似的。关于CMS的垃圾回收的几个阶段可以回顾王子的上篇文章探索ParNew和CMS垃圾回收器。

首先我们要弄明白,什么时候会触发新生代和老年代的混合垃圾回收?

G1有一个参数“-XX:InitiatingHeapOccupancyPercent”,默认值为45%。

什么意思呢?就是说当老年代占据了堆内存的45%的Regionf的时候,就会触发混合垃圾回收。

 

具体流程是什么样的呢?

首先会触发一次初始标记操作,这个过程是要“Stop the World”的,对应的就是CMS的初始标记阶段,细节不再说明。

接着会进入并发标记阶段,这个阶段同样对应CMS的并发标记阶段,不再说明。

接着会进入最终标记阶段,这个阶段其实和CMS的重新标记阶段也基本一致。

最后就是混合回收阶段,这个阶段和CMS的并发清理阶段就不太一样了,这个阶段会计算每个Region中的存活对象数量,存活数量占比,还有执行垃圾回收的耗时等问题。

接着会进入“Stop the World”阶段,然后全力以赴进行垃圾回收,并尽量保证停止时间不超过我们设定好的时间,所以可能只会回收掉之前标记好的一部分垃圾对象。

为什么要叫做混合回收呢,因为它不仅仅回收的是老年代,新生代和大对象的Region也会同时进行回收,而具体回收哪些Region就要视情况而定了,根据价值回收价值G1会自己做出选择。

而混合回收是可以进行多次的,比如先停止系统,混合回收掉一部分Region,再停止系统,再执行一次混合回收。

有参数可以控制这个数量,“-XX:G1MixedGCCountTarget”参数,就是在一次混合回收的过程中,最后一个阶段执行几次,默认是8次。

 

为什么要这样反复多次的回收呢?

因为这样每次回收停止系统的时间都很短,在回收的间隙系统是可以正常运行的。

 

还有个参数“-XX:G1HeapWastePercent”,默认值是5%。

它的意思是,混合回收的时候,都是基于复制算法进行的,把Region存活的对象放入其他Region,然后清除掉本来的Region。那么当空闲的Region数量达到堆内存的5%,就会立即停止混合回收。

而通过这种复制算法回收,也不会出现像CMS标记清理算法导致的内存碎片问题。

 

还有个参数“-XX:G1MixedGCLiveThresholdPercent”,默认值是85%,意思就是回收Region的时候,存活的对象必须少于85%才可以被回收掉。否则存活对象太多,复制的时候成本是很高的。

 

如果回收失败怎么办?

如果在复制的时候发现没有空闲的Region可以承载存活的对象,那么会触发失败,立马停止系统进程,采用单线程进行标记、清理和压缩整理,空闲出一批Region,这个过程是极慢的。

 

总结

本文我们对G1的内存机制和垃圾回收的算法做了一个比较清晰的解释。

阅读完本文,相信小伙伴们自己可以总结出G1和CMS究竟有什么不一样了吧。

欢迎小伙伴们留言区讨论G1和CMS的区别,王子会第一时间回复。

那我们下篇文章再见。

 

 

往期文章推荐:

大白话谈JVM的类加载机制

JVM内存模型不再是秘密

轻松理解JVM的分代模型

秒懂JVM的垃圾回收机制

探索ParNew和CMS垃圾回收器

探索G1垃圾回收器

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsffp.html