JVM七大基本的垃圾收集器

[toc]

serial

新生代的垃圾收集器,很古老,只有单线程,且不能和用户线程同时运行。但是在有限的内存空间,程序不大的情况下还是可以用的,适合桌面应用,但是现在几乎不用Java做桌面应用了,所以用的很少很少。

parNew

新生代的垃圾收集器,多线程,且可以和用户线程并发执行,jdk7之前,除了serial只有它可以和cms配合使用。所以jdk7之前大量使用。虽然parNew是多线程的,但是如果是单核处理器,内存有限的情况下,serial可能会比parNew更优秀,因为它没有线程之间切换的开销。

CMS

jdk5出的收集器,是一款老年代收集器,它最大的特色是可以和用户线程并发执行。也是多线程的。它注重响应时间,也就是尽可能缩短垃圾收集时间。它有四个步骤: 

1.初始标记

初始标记是标记GC Root能直接关联到的对象,速度很快,不能和用户线程同时执行。

2.并发标记

开始从GC Root直接关联对象遍历整个对象图,这个过程很耗时间,但是可以和用户线程并发执行。

3.重新标记

修正并发标记期间变动的那一部分对象记录,时间短,不能和用户线程并发执行。

4.并发清除

清理删除掉已经死亡的对象,用的标记清除,所以不需要移动存活对象,用户线程也就不需要停下来。

优缺点

1.占用资源,处理器核心数量太少的话,很占用系统资源,就会降低吞吐量; 

2.会有“浮动垃圾”,因为并发标记和并发清除阶段,用户线程还在运行,所以可能还会生成对象,所以使用CMS的时候不能等到老年代满了才触发GC,需要留一定的空间,jdk1.6是留8%,但是如果这8%不够用呢?就会触发并发失败,停止所有用户线程,启用serial Old来收集垃圾。 

3.用的标记清除算法,会有内存碎片,可能会导致没有连续空间而触发下一次Full GC,但是jdk9之前也有参数可设置CMS执行多少次之后会进行一次碎片整理。

# parallel Scavenge

parallel Scavenge也是一款新生代收集器,它最大的特点是之前出的收集器都是尽可能缩短垃圾收集时间,但是它是专注于达到一个可控制的吞吐量,吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 运行垃圾收集时间),有两个参数,分别是控制垃圾收集最大时间,一个是控制吞吐量

serial old

serial old收集器是一个款老年代收集器,单线程,使用标记整理算法,好处是没有空间碎片,但是单线程,不能和用户线程并发,是其最大的缺点。但是它也是CMS收集器收集失败后的备选收集器。

parallel old

是parallel Scavenge的老年代版本,多线程,可以和用户线程并发执行,基于标记整理算法,没有内存碎片。parallel old出现后,paralle Scavenge才发挥出最大的用处,在吞吐量优先,内存资源有限的情况下,可以考虑用parallel Scavenge + parallel Old

 jdk9

jdk9之后,官方推荐使用G1收集器,所以取消了parNew + serial Old和serial + CMS的组合,parNew 和 CMS也只能组合使用,不能单独使用了。

G1

G1收集器和上面讲的收集器最大的不同是,它是一个全方位的收集器,它不固定只收集新生代和老年代,在它眼里小孩子才做选择,成年成统统都要,它直接收集整个堆,它把堆分成了一个一个的Region,每个Region都可以扮演新生代的Eden,Survivor,老年代空间,它还有专门存储大对象的地方,它认为只要超过一般Region空间的对象都是大对象,然后把他们单独放一块,当作老年代对象处理。G1收集器会根据用户设置的收集时间,优先收集那些收益最大的Region空间。其实G1应属于比较高级一点的收集器吧,还有其他的后面再将吧。

你可能感兴趣的:(JVM七大基本的垃圾收集器)