JVM 垃圾回收器分类
JVM 垃圾回收器分类
JVM垃圾回收器是Java虚拟机中非常重要的一部分,负责自动管理内存,释放不再使用的对象所占用的内存空间。不同的垃圾回收器在实现机制、性能特点和适用场景上都有所不同。本文将详细介绍7种常见的JVM垃圾回收器,帮助读者更好地理解它们的特点和使用场景。
JVM 垃圾回收器分类
本节主要讲解7种垃圾回收器,其中有3种垃圾回收器是作用于年轻代垃圾回收的收集器;另外3种圾回收器是作用于老年代垃圾回收的收集器;剩余的1种垃圾回收器能够同时作用于年轻代和老年代。
7种垃圾回收器以及其作用的内存区域如下图所示:
通篇皆为重点知识,请认真学习并理解每种垃圾回收器的特点。
Serial收集器
基本概念:Serial收集器是最基本、发展历史最久的收集器,这个收集器是采用复制算法的单线程的收集器。
Tips:从概念上来看,我们需要注意Serial收集器的两个特点:一个是采用复制算法,另外一个是单线程收集。
单线程的收集器:单线程一方面意味着他只会使用一个CPU或一条线程去完成垃圾收集工作,另一方面也意味着他进行垃圾收集时必须暂停其他线程的所有工作,直到它收集结束为止。
不过实际上到目前为止,Serial收集器依然是虚拟机运行在Client模式下的默认新生代收集器,因为它简单而高效。Serial收集器运行过程如下图所示:
Parnew收集器
基本概念:Parnew收集器其实就是Serial收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为和Serial收集器完全一样,但是他却是Server模式下的虚拟机首选的新生代收集器。
Tips:从概念上来看,我们需要注意Parnew收集器的两个特点:一个是采用复制算法,另外一个是多线程收集。
特点:
- 除了Serial收集器外,目前只有它能与CMS收集器配合工作。CMS收集器第一次实现了让垃圾收集器与用户线程基本上同时工作;
- Parnew收集器默认开启的收集线程数与CPU数量相同,在CPU数量非常多的情况下,可以使用-XX:ParallelGCThreads参数来限制垃圾收集的线程数。
Parnew收集器运行过程如图所示:
Parallel Scavenge收集器
基本概念:Parallel Scavenge收集器也是一个新生代收集器,也采用了复制算法,也是并行的多线程收集器。Parallel Scavenge收集器的目标是达到一个可控制的吞吐量。Parallel Scavenge收集器是虚拟机运行在Server模式下的默认垃圾收集器。被称为“吞吐量优先收集器”。
Tips:从概念上来看,我们需要注意Parallel Scavenge收集器的三个个特点:一个是采用复制算法,一个是多线程收集,一个是达到控制吞吐量的目标。
Parallel Scavenge收集器运行过程同Parnew收集器一样:
控制吞吐量:CMS等收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量。所谓吞吐量就是CPU用于运行用户代码时间与CPU总消耗时间的比值,即
吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。
空间吞吐量参数介绍:虚拟机提供了-XX:MaxGCPauseMills和-XX:GCTimeRatio两个参数来精确控制最大垃圾收集停顿时间和吞吐量大小。不过不要以为前者越小越好,GC停顿时间的缩短是以牺牲吞吐量和新生代空间换取的。由于与吞吐量关系密切,Parallel Scavenge收集器也被称为“吞吐量优先收集器”。
Parallel Scavenge收集器有一个参数-XX:UseAdaptiveSizePolicy参数,这是一个开关参数,这个参数打开之后,就不需要手动指定新生代大小、Eden区和Survivor参数等细节参数了,虚拟机会根据当前系统的运行情况以及性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量。
如果对于垃圾收集器运作原理不太了解,以至于在优化比较困难的时候,可以使用Parallel Scavenge收集器配合自适应调节策略,把内存管理的调优任务交给虚拟机去完成。
Serial Old收集器
基本概念:Serial Old收集器同样是一个单线程收集器,作用于老年代,使用“标记-整理算法”,这个收集器的主要意义也是在于给Client模式下的虚拟机使用。
Serial Old收集器运行过程如图所示:
Parallel Old收集器
基本概念:Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理算法”进行垃圾回收。
这个收集器在JDK 1.6之后的出现,“吞吐量优先收集器”终于有了比较名副其实的应用组合,在注重吞吐量以及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge收集器+Parallel Old收集器的组合。
Parallel Scavenge收集器+Parallel Old收集器的组合运行过程如下图所示:
CMS收集器
基本概念:CMS(Conrruent Mark Sweep,连续标记扫描)收集器是以获取最短回收停顿时间为目标的收集器。使用标记-清除算法。
收集步骤:收集过程分为如下四步:
- 初始标记:标记GCRoots能直接关联到的对象,时间很短;
- 并发标记:进行GCRoots Tracing(可达性分析)过程,时间很长;
- 重新标记:修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,时间较长;
- 并发清除:回收内存空间,时间很长。其中,并发标记与并发清除两个阶段耗时最长,但是可以与用户线程并发执行。
CMS收集器运行过程如下图所示:
G1收集器
基本概念:G1是目前技术发展的最前沿成果之一,HotSpot开发团队赋予它的使命是未来可以替换掉JDK1.5中发布的CMS收集器。
与其他GC收集器相比,G1收集器具有以下特点:
- 并发和并行:使用多个CPU来缩短Stop The World停顿时间,与用户线程并发执行;
- 分代收集:独立管理整个堆,但是能够采用不同的方式去处理新创建对象和已经存活了一段时间、熬过多次GC的旧对象,以获取更好的收集效果;
- 空间整合:基于标记-整理算法,无内存碎片产生;
- 可预测的停顿:能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集器上的时间不得超过N毫秒。
在G1之前的垃圾收集器,收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分(可以不连续)Region的集合。
小结
本节主要讲解了7种垃圾收集器:Serial收集器,Parnew收集器,Parallel Scavenge收集器,Serial Old收集器,Parallel Old收集器,CMS收集器和G1收集器。
其中专门针对年轻代的收集器有Serial收集器,Parnew收集器和Parallel Scavenge收集器;专门作用于老年代的收集器有Serial Old收集器,Parallel Old收集器和CMS收集器;而G1收集器即能够作用于年轻代,也能够作用于老年代。
学习者需要对这7种垃圾回收器进行理解,并掌握其作用的内存区域。