大家好,我是树哥。之前我们讲过CMS收集器,当时我们说CMS收集器已经过时了,应该是时候使用G1收集器了。那么G1收集器到底有什么神奇之处,又比CMS收集器好在哪里呢?今天就让舒哥带大家来一盘吧!文章思维导图G1Recycler的历史G1(Garbage-First)回收器早在JDK1.7就确定要做,但直到JDK7u4才正式推出。JDK9后成为默认的垃圾收集器,CMS收集器同时被废弃。G1收集器特点G1收集器是服务端应用程序的垃圾收集器,其长期使命是取代CMS收集器。与CMS收集器相比,G1收集器有相似之处。比如都是关注GC停顿时间,采用分代收集思想的收集器。但从整体实现上来看,G1收集器做了很多改进,可以说是对CMS收集器的全面改进。G1收集器与CMS收集器相比,有以下不同点:采用partitioningintoparts的思想,采用mark-sorting垃圾收集算法,可预测的GC暂停时间,对CMS和之前采用partitioning的思想collectors比如它的JVM内存空间按照generation的思路被划分成一个很大的物理上连续的区域,如下图所示。而在G1收集器中,虽然也采用了分代的思想,但是并没有为其分配一块连续的内存,而是将整块内存分成几部分,拆分成Region,如下图所示。如上图所示,G1收集器不再为新生代和老年代划分大块内存,而是将它们划分为Region,每个Region标记为新生代或老年代。在G1中,多了一个Humongous区,为大对象优化分配而生。G1收集器分块的Region设计思想是G1收集器比CMS收集器更强大的核心。G1收集器通过对大块内存进行归零,可以更灵活地控制GC暂停时间,同时也解决了CMS收集器的内存碎片问题和大内存下GC暂停时间长的问题。G1收集器和CMS收集器的另一个很大区别是G1收集器使用的是“标记-排序”算法,而CMS收集器使用的是“标记-清除”算法。所以CMS收集器会产生大量的内存碎片,而G1收集器则没有这个问题。可能有朋友会问:那为什么CMS回收器不用“标记-组织”算法呢?很简单,由于CMS收集器的老年代较大,使用“mark-compact”算法需要较长的GC停顿时间,从而导致接口响应时间较长。其实CMS收集器提供了-XX:+UseCMSCompactAtFullCollection参数来实现内存压缩,但是内存压缩的时候GC停顿时间会很长,导致接口响应时间变长。好奇宝宝又问了:G1回收器也是用了“标记-排序”算法,为什么不会造成GC停顿时间长呢?很简单,因为G1收集器使用了划分region的思想,将大块的内存划分成部分,成为region。此外,它还维护了一个待回收Region列表,可以选择回收成本最高的Region进行回收,从而实现对GC停顿时间的灵活控制。你有看到它吗?G1采集器的Region设计思路真是G1采集器的一大杀器!可预测的暂停时间G1收集器对于CMS来说还有一个很大的优势,那就是它可以建立一个可预测的暂停时间模型,让用户可以明确指定在M毫秒的时间段内,垃圾将被消耗收集时间不得超过N毫秒。对于这个特性,还是比较少用的,大家可以学习一下。垃圾收集过程与CMS收集器相比,G1收集器的垃圾收集过程比较特殊。它使用两种垃圾收集方式:“年轻代收集”和“混合收集”。新生代收集应用刚启动时,流量慢慢进来,JVM开始生成对象。G1会选择一个分区,指定eden分区。当分区满时,G1会选择一个新的分区作为eden分区。这个操作会一直持续到达到eden分区的上限,然后触发新生代收集。年龄收集采用“复制算法”,首先使用单伊甸园和双幸存者迁移幸存对象。在迁移过程中,对象会根据对象的年龄等特征被提升到老年代分区,而原来的年轻代分区将被完全回收。这个过程涉及的规则和CMS收集器类似,只是G1收集器将内存分零。混合集合随着时间的推移,越来越多的对象被提升到老年代。当老年代的比例(Java堆内存的比例)达到InitiatingHeapOccupancyPercent参数时,JVM会触发“混合回收”进行垃圾回收。需要注意的是,混合收集会收集新生代和部分老年代的内存,不等同于FullGC。FullGC将回收整个老年代内存。对于混合采集方法,采集过程可以分为4个阶段:初始标记、并发标记、最终标记、初始标记的筛选和恢复。这个阶段和CMS回收器一样,只是简单的标记GCRoots可以直接关联的对象,这样后续的GC回收线程就可以和用户线程并发执行了。初始标记阶段需要“停止世界”。并发标记。此阶段与CMS收集器相同。它从GCRoot开始,分析堆中对象的可达性,找出存活的对象。该阶段耗时较长,但无需“StoptheWorld”即可与用户程序并发执行。最终标记。这个阶段和CMS收集器一样,都是为了修复并发标记时用户程序继续运行导致引用变化的问题。只是G1收集器使用了不同的方法来实现而已。在这个阶段,需要“停止世界”。筛选恢复。这个阶段和CMS收集器的并发清除是一样的,都是清除标记为垃圾的对象。仅针对G1收集器,它会维护每个Region的回收值和成本,然后根据用户预期的GC停顿时间指定回收计划。从《深入理解 Java 虚拟机》整体来看,我们会发现G1回收器的混合回收过程和CMS回收器很相似,都经历了几个阶段:初始标记、并发标记、最终标记、筛选和回收(并发清算)。总结从JDK7正式推出到JDK9成为默认垃圾收集器,G1收集器用了两代才打败CMS收集器。从G1收集器的实现来看,其开创性的Region设计思想无疑是打败CMS收集器的秘诀。通过这种设计思路,G1回收器可以更灵活地控制GC停顿时间,也可以实现更高效、更复杂的功能,例如:根据回收空间和耗时选择最佳回收Region,预测GC停顿时间,ETC。参考资料的名字解释的很好!贵宾!理解G1垃圾收集器-GrimMjx-博客园关于GC流程,写得好!贵宾!JavaHotspotG1GC的一些关键技术-美团技术团队08大厂面试问题:有了G1,还需要其他垃圾收集器吗?.md官方资料!贵宾!垃圾优先垃圾收集器调整|甲骨文中国官方资料!贵宾!垃圾回收期推荐使用场景!JavaHotSpot垃圾收集就OK了!贵宾!5张图带你吃透G1垃圾收集器-.COMG1垃圾收集器详解-掘金深入理解Java虚拟机系列-12垃圾收集03-常用垃圾收集器详解-掘金深入理解JAVA垃圾收集CMS,G1工作流程原理-掘金GC-G1Java垃圾收集器详解|Java全栈知识体系VIP!有美团的具体做法!GC-ZGCJava垃圾收集器详解|Java全栈知识体系《深入理解 Java 虚拟机》CMS垃圾收集器问题及解决方案-程序员大本营
