JVM的GC算法

2020-03-11  本文已影响0人  掩流年

GC分代假说

我们都知道,绝大多数对象都是朝生夕死。对于绝大多数GC算法而言都会遵循基本的分代假设。
它的结构如下所示,即


分代假说
Young

此区域使用的GC算法为Mark and Copy,即没被回收的对象会被标记出来然后拷贝到幸存区。

Tenured(Old)

在老年代,使用的GC算法是Mark-Sweep-Compact,即没被回收的对象,会被标记出来,然后为了减少内存碎片,尽量的压缩成一块区域。
在老年代调用的使用的是Major GC区回收

PermGen/Metaspace

GC收集器

GC Mark

我们下面介绍的垃圾回收器有三种SerialParallelCMSG1

垃圾收集算法
Serial

serial回收算法如上图,分别应用在年轻代和老年代。基本和分代假说的说法一样,一根线程,从年轻代的标记复制,到STW,到老年代的标记清除整理。

Parallel

串行回收的并发版本,所作的事情是一样的。
我们可以从上图中看到的是,Parallel有三个回收器,即ParNew,Parallel Old,Parallel Scavenge,其中Parallel OldParallel Scavenge是搭配使用的。至于ParNew是因为CMS回收器只能回收老年代,它被开发出来用于和CMS搭配使用,回收年轻代。

CMS
GC回收算法对比

我们可以看到左边是一个串行收集器,右边是CMS收集器,这两个对比起来,CMS的STW过程Initial Mark是一个比较短暂的过程,然后标记过程会和用户线程一起去执行,但是可能执行标记的不准确, 所以在之后的一段时间,又STW一会,并发去Remark标记。之后在清除的过程中,和用户线程并发的执行。

并且在CMS中,老年代只进行Mark-Sweep,而不进行Compact,主要用于低延时的系统。

G1

G1在Java9之后成为了默认的GC。如果想在Java8中使用它,可以加个参数Use G1 GC。

它横跨了年轻代和老年代,它制定的目标是软实时,比较大的堆内存(大于4G),可以设定目标(设定停顿时间,尽量达到)。

在G1的设计中,没有分代假说的存在了。它会将堆分成若干个等大的区域。


G1

再回收的时候无需回收整个堆,而是回收一个Collection Set,即一个区域的集合。
在GC1中,有两种GC:

上一篇下一篇

猜你喜欢

热点阅读