当前位置: 首页 > 科技观察

Java8的G1垃圾收集器相比之前的CMS有什么特别之处?

时间:2023-03-12 06:22:07 科技观察

本文转载自微信公众号《Java极客技术》,作者鸭血范。转载本文请联系Java极客技术公众号。CMSCMS垃圾收集器,全称ConcurrentMarkSweepConcurrentmark-clear,从名字我们也可以看出这个垃圾收集器是基于mark-sweep算法实现的。首先,“并发”意味着GC线程可以和用户线程并发执行。同时,由于是mark-sweep算法,也就意味着垃圾回收器会产生大量的碎片,这也是mark-sweep算法的缺点。同时CMS是作用于老年代的,老年代的垃圾回收频率会低于年轻代。CMS垃圾回收有四个初始标记过程:并发标记:重新标记:并发清除:初始标记是一个STW(stoptheworld)过程,所有用户线程都会停止。这个时候只要标记GCRoots就可以直接到达的对象,因为只标记了一层,所以整体速度会比较快。Concurrentmarking是一个GCRootsscanning的过程,会扫描整个链接,标记出可以回收的对象;由于整个链接会比较长,所以会花费比较长的时间,但是因为这个过程是并发的,所以没必要让用户线程的运行不受影响。顾名思义,re-marking就是重新标记的过程,也会是STW。之所以有这个重标记过程,是因为在上一步并发标记的时候,用户线程还在运行,所以对象的引用关系会发生变化。同时,运行过程中会产生新的垃圾。只有在上一步中更改过的对象才会在此处标记。虽然它会是STW,但它会更快。并发清算是最后一个阶段。这个阶段比较耗时,因为需要清除之前扫描的所有垃圾对象。但是这个阶段可以并发执行,不会影响用户线程的运行。经过以上四个过程,一个完整的GC就完成了。前面我们提到,整个CMS垃圾收集器都是基于mark-sweep算法的。它首先通过三个过程标记需要清理的对象,然后清理它们。初始标记和重新标记在整个过程中触发STW,其他两个阶段同时进行。mark-clear算法会产生内存碎片,所以不适合需要频繁回收的younggeneration,只适合oldgeneration。碎片化是CMS的劣势,并发是CMS的优势。毕竟,任何收藏家都会有优点和缺点。G1之前我们讲完了CMS。接下来说说G1。G1的全称是GarbageFirst。在谈G1垃圾收集器的细节之前,首先我们需要知道的是G1重新定义了整个堆空间。G1中的老年代和年轻代不再是物理上的隔离,而是逻辑上的隔离。在G1中,整个堆空间被划分为大小相同的Region块,多个Region块在逻辑上形成新生代和老年代。这样做的目的是因为垃圾回收时不需要扫描整个堆空间,可以按照指定的暂停时间进行垃圾回收。G1会量化每个Region的恢复成本,从而做到成本可控,在有限的停顿时间内完成恢复,这是G1最大的特点。G1回收也分为四个过程:Initialmarking:Initialmarking,CMS也只扫描直接连接到GCRoots的对象。这个阶段也需要STW,但是时间也很短;并发标记:从GCRoots开始,对堆中的对象进行Reachability分析,寻找存活对象。该阶段耗时较长,但可以与用户程序并发执行;finalmarking:finalmarking和CMSre-marking的思路一直都是,也是为了在并发标记的时候纠正用户程序并发运行导致mark改变的那部分对象,但是不同的是G1会在线程RememberedSetLogs中记录这段时间对象的变化。最后的标记阶段需要将RememberedSetLogs的数据合并到RememberedSet中。这个阶段需要暂停线程,但是可以并行执行;过滤器回收:过滤器回收的最后一步是G1和CMS最大的区别。G1首先对每个需要回收的Region进行成本量化和排序,结合用户预期的GC停顿时间制定回收计划,通过-XX:MaxGCPauseMillis参数指定预期回收时间。这个阶段也可以和用户程序并发执行,但是因为只回收了一部分Region,所以时间是用户可控的,暂停用户线程会大大提高回收效率。上面提到了一个RememberedSet内存集,用来记录对象引用。当一个对象引用在并发标记过程中发生变化时,它会被记录在这里,并在最终被标记时被更正。整体来说,G1使用了mark-sort算法进行垃圾回收,不会像CMS一样产生内容碎片,所以G1可以同时对新生代和老年代进行垃圾回收,比CMS更加灵活。并且由于G1将内存划分为Region,所以不会出现复制算法造成的空间浪费问题。总结首先,CMS和G1都是并发分代垃圾收集器,都是低延迟的;CMS基于mark-clear算法,只适合在新生代使用,停顿时间不可预测。同时,年轻一代和老一代在物理上是隔离的。G1是一种基于标记排序的高吞吐量、可预测的暂停时间垃圾收集器。可以在新生代和老年代同时使用,新生代和老年代在逻辑上是隔离的。特性G1CMS算法Mark-SortMark-ClearYoungGeneration和OldGeneration逻辑隔离物理隔离PauseTimePredictableRowYesNo并发和GenerationSupportSupportThroughputHighLowUsageScenarioYoungGeneration,OldGenerationYoungGenerationLowLatencyYesYes