JVM学习笔记——垃圾收集器

title: JVM学习笔记——垃圾收集器
date: 2018/9/4 17:09:31
description: 最近开始着手JVM的学习,在这里把自己学习过程中的笔记分享出来,希望能帮到一些小伙伴,同时也是对自己的学习的一个梳理。

垃圾收集器

垃圾收集器内容颇多,但算法原理都是基于垃圾收集算法,故这里只简单介绍一下各收集器的特点。

HopSpot中的收集器群

JVM学习笔记——垃圾收集器


两个虚拟机之间的连线表示它们可以搭配使用,反之则不能搭配。

Serial收集器

Serial&Serial Old

使用“标记-整理”算法

“单线程”收集器,这里的单线程指的是Serial在对某一条线程执行收集工作时,必须暂停其他线程的运行,这就会造成大量的GC停顿出现。

优点是简单高效,在Client模式的虚拟机中表现优秀。

Serial Old收集器

Serial的老年代版本,特性基本与Serial一致。

在JDK1.5之前可以与Parallel搭配使用,或者作为CMS的后备方案。

ParNew收集器

JVM学习笔记——垃圾收集器

ParNew就是针对Serial改进的多线程版本。

在很多虚拟机中,ParNew却是新生代的首选收集器,因为除了Serial只有它能够与CMS搭配使用。

Parallel Scavenge收集器

Parallel Scavenge&Parallel Old

是一个新生代的收集器,使用多线程+复制算法。

主要关注吞吐量的收集器吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间),提供两个参数用于精确控制吞吐量:

-XX:MaxGCPauseMillis,最大GC停顿时间。允许的值是一个大于0的毫秒数,收集器尽可能保证收集时间不超过该值。注意,停顿时间缩短需要牺牲吞吐量和空间,更小的停顿时间可能会导致更频繁的GC。

-XX:GCTimeRatio,GC时间占总时间比率。是一个0-100之间的整数,等于吞吐量的倒数。

Parallel Old收集器

Parallel Scavenge的老年代版本,使用多线程+标记整理算法。

由于Serial Old在服务端上性能不佳,故有了该收集器与Parallel Scavenge进行搭配使用。

CMS收集器(Concurrent Mark Sweep)

JVM学习笔记——垃圾收集器

基于标记-清除算法实现,是一款以获取最短GC停顿时间为目标的收集器。它的运作过程分为4步:

初始标记
标记GC Roots能关联到的对象。

并发标记
由GC Roots发起对象的跟踪,验证是否可达。

重新标记
修正并发标记期间变动的一部分对象的标记记录。

并发清除
清除标记对象的空间。

其中只有初始标记与重新标记两个过程需要进行停顿,但是这两个过程仅仅是标记,速度很快,最漫长的清除过程在CMS下可以与用户线程并行处理。

CMS虽然很强大,但还是有着以下3个缺点:

虽然CMS不会导致GC停顿,但并发的代价就是会占用CPU资源,可能会导致用户程序变慢,在核数较低的CPU中该问题会越发明显。

由于CMS的清理不会暂停用户线程,可能导致“浮动垃圾”的出现,那就需要留出一部分内存空间对应“浮动垃圾”,所以CMS有一个触发回收的内存比例,在JDK1.6中该值默认为92%。如果预留的内存还是无法满足程序需求,CMS就会启动备用方案(一般是Serial Old)来重新进行收集。

由于CMS使用的是标记-清除算法,所以会有大量的内存碎片产生,会导致大对象找不到空间存放而提前触发一次Full GC进行内存整理。

G1收集器 在JDK1.7之后才出现的收集器,G1具备以下四个特点:

并行与并发,能利用多线程,多CPU的优势,使得GC与用户线程并行。

G1能够独自对整个GC堆进行管理,并且留有了分代的特性,可以根据不同的区域采用不同的方式处理。

将Java堆划分为多个大小相等的独立区域(Region),在Region上来看是基于复制算法实现的,从整体上看是基于标记-整理算法实现,结合了两种算法的优点。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsspjj.html