JVM 并发垃圾收集算法

2017-09-09  本文已影响0人  wangdy12

CMS 和 G1 算法

CMS GC (-XX:+UseConcMarkSweepGC)

并发标记扫描(Concurrent Mark Sweep,CMS)专为需要较短暂停的应用而设计的老年代收集器,在应用程序运行时需要与GC线程共享处理器资源,所以需要运行在多核处理器上。通常,在具有较多长生命周期数据集(老年代比较大)的应用程序上使用,从JDK 9 开始不推荐使用CMS收集器,推荐使用Garbage-First收集器

流程

每次major collection,CMS收集器会在收集开始时暂停所有应用程序线程,叫做initial mark pause,在并发跟踪阶段结束后会再次暂停,叫做remark pause,第二次暂停往往时间较长,通常与minor collection相当,两个暂停期间都是多个线程执行收集工作

Concurrent Mode Failure

CMS收集器使用一个或多个与应用程序线程同时运行的垃圾收集器线程,目标是在老年代变满之前完成收集

在正常操作中,CMS收集器在应用程序线程仍在运行时执行大部分的跟踪和清除工作,因此应用程序线程只会有短暂的暂停。但是,如果CMS收集器无法在老年代填满之前完成垃圾回收,或者老年代中的可用空闲块不能满足分配需求,则所有应用程序都将暂停,等待收集完成。无法并发完成收集的情况称为并发模式失败,表示需要调整CMS收集器参数

启动时机

串行收集器只要老年代变满就进行major collection,在收集过程中停止所有应用线程
CMS收集器中并发收集必须定时开始,以便GC可以在老年代填满之前完成,否则会产生并发模式故障Concurrent Mode Failure,导致更长的暂停,CMS内部会根据历史记录,对老年代内存被填满的剩余时间以及并发的收集时间进行估计,确保在老年代用尽之前完成GC,避免并发模式故障

由于要预留空间给浮动垃圾,如果老年代的内存占用率超过CMS初始化占用比例,同样也会触发CMS,调整触发CMS的老年代百分比-XX:CMSInitiatingOccupancyFraction=<N>

缺点

G1 (XX:+UseG1GC)

Garbage-First(G1) 垃圾收集器适用于具有大量内存的多处理器计算机,它在延迟和吞吐量之间寻找一个最佳平衡,JDK 9开始作为默认GC

特点:

G1是一个分代收集收集器,将堆分成新生代和老年代,算法是并行的,大部分阶段是并发运行,部分操作会产生STW暂停,空间回收是逐步增加的,主要通过疏散的方式进行。G1通过跟踪先前应用程序行为和垃圾收集暂停的信息来建立相关成本的模型,从而实现可预测性,通过模型确定暂停时间内要完成的工作量,首先在最有价值的区域中回收空间(即区域中大部分都是垃圾,这也是G1名称的由来)

G1主要通过疏散evacuation回收空间:在选定区域内的活动对象会被复制到新的内存区域,同时在此过程中进行整理将对象放在一起,疏散完成后,先前占用的空间就可以回收利用

G1收集器有很高的概率,满足设定的GC停顿时间,但是并不绝对完成,所以G1不是一个实时的收集器(real-time collector)

堆布局

G1将堆分区为一组大小相等的区域,每个区域都是一个连续的虚拟内存区域,区域是内存分配和内存回收的单位,在某一时间,这些区域可以是空的,或者分配给了年轻代或老年代

区域的大小通过-XX:G1HeapRegionSize设定,默认区域大小基于堆的初始和最大大小,堆包含大约2048个区域。堆区域的大小可以在1到32 MB之间变化,但必须是2的幂次

这里貌似限定了堆空间的最大值就是64GB?

G1堆分配

Humongous Objects

巨型对象是大于或等于半个区域大小的对象

垃圾收集周期

G1收集器在两个阶段之间交替:

如果应用程序在垃圾回收时内存不足,则G1会像其他收集器一样STW,执行Full GC

Collection Set:将要被GC收集的region集合,内部的存活对象在GC期间都会被疏散(复制/移动)

young-only阶段,收集的区域集合(Collection Sets)仅由新生代区域组成,G1每次在年轻代收集的末尾计算新生代的大小,在下一个阶段改变。如果没有另外约束,则G1自适应地在-XX:G1NewSizePercent-XX:G1MaxNewSizePercent之间调整大小来满足暂停时间的要求

space-reclamation阶段,G1试图最大化回收老年代的内存,按照回收的效率高低清理老年代区域,同时通过剩余可用时间确定最终收集区域的大小,活动对象比例在-XX:G1MixedGCLiveThresholdPercent阈值之上的不进行清理,-XX:G1MixedGCCountTarget设定该阶段中进行Mixed垃圾收集的次数

当收集集候选区域(collection set candidate regions)中可回收的空间量小于-XX:G1HeapWastePercent设置的百分比时,结束该阶段

确定启动堆占用率

启动堆占用百分比(Initiating Heap Occupancy Percent, IHOP)是触发初始标收集的阈值,定义为老年代大小的百分比

G1默认情况下通过观察标记所花费的时间以及在标记周期内老年代分配的内存数量来自动确定最佳的IHOP,此功能称为自适应IHOP。如果此功能处于活动状态,-XX:InitiatingHeapOccupancyPercent只有在没有足够的观察值来进行预测时使用,选项-XX:-G1UseAdaptiveIHOP可以关闭G1的自适应调整,此时一直通过-XX:InitiatingHeapOccupancyPercent确定阈值

标记

G1标记使用Snapshot-At-The-Beginning (SATB) 算法。 在Initial Mark暂停时获取堆的虚拟快照,在标记开始时存活的所有对象在后来的标记过程中都认为是存活对象。这意味着在标记期间变为死亡(无法访问)的对象在空间回收阶段仍然被认为存活,进行疏散 ,与其他收集器相比,这可能会导致错误地额外保留一些内存。但是,SATB可以降低Remark阶段的延迟

上一篇 下一篇

猜你喜欢

热点阅读