上一篇博客我们介绍了Java虚拟机垃圾回收,介绍了几种常用的垃圾回收算法,包括标记-清除,标记整理,复制等,这些算法我们可以看做是内存回收的理论方法,那么在Java虚拟机中,由谁来具体实现这些方法呢?
没错,就是本篇博客介绍的内容——垃圾收集器。
1、垃圾收集器种类事实上Java虚拟机规范对垃圾收集器应该如何实现,并没有任何的规定,所以不同的厂商、不同版本的虚拟机所提供的垃圾收集器都会有所不同,并且一般都会提供参数供用户根据自己的应用特点和要求组合出各个年代所使用的收集器。
下图是基于 Sun HotSpot 虚拟机1.6版 Update 22的虚拟机种类:
由上图我们可以总结出几个结论:
①、新生代垃圾收集器:Serial、ParNew、Parallel Scavenge;
老年代垃圾收集器:Serial Old(MSC)、Parallel Old、CMS;
整堆垃圾收集器:G1
②、垃圾收集器之间的连线表示可以搭配使用,有如下几种组合:
Serial/Serial Old、Serial/CMS、ParNew/Serial Old、ParNew/CMS、Parallel Scavenge/Serial Old、Parallel Scavenge/Parallel Old、G1;
③、串行收集器Serial:Serial、Serial Old
并行收集器 Parallel:Parallel Scavenge、Parallel Old
并发收集器:CMS、G1
ps:对于文章中有一些名词不理解的,可以先看本篇博客最后一个小节。
2、Serial收集器这是一个最基本,历史最悠久的垃圾收集器,是JDK1.3之前新生代唯一的垃圾收集器。
该收集器有如下特点:
①、作用于新生代
由上图也可看出,这是一个新生代垃圾收集器,采用的垃圾回收算法是复制算法。
②、单线程
工作时只会使用一个CPU或者一条收集线程去完成工作。
③、进行垃圾收集时,必须暂停所有工作线程
也就是说使用Serial收集器进行垃圾回收时,别的工作线程都暂停,系统这时候会有卡顿现象产生。
④、适用场景
Serial 收集器由于没有线程交互的开销,对于限定单个CPU的环境,可以获得最高的单线程收集效率。
一般在用户的桌面场景中,分配给虚拟机管理的内存一般来说不会很大,收集几十兆或一两百兆的新生代,定顿时间可以控制在几十毫秒,只要不是频繁发生的,这点停顿是可以接受的。
所以 Serial 收集器对于运行在 Client 模式下的虚拟机是一种很好的选择。
3、ParNew收集器这个收集器其实就是Serial收集器的多线程版本。
也就是说其特点除了多线程,其余和Serial收集器一样,事实上,这两个收集器实现上也共用了很多代码。
①、作用于新生代
一个新生代垃圾收集器,采用的垃圾回收算法是复制算法。
②、多线程
弥补了Serial收集器单线程的缺陷。
③、适用场景
由于其多线程的特性,是大多数运行在 Server 模式下的虚拟机首选新生代垃圾收集器。
另外需要说明的是,能够与下面将要介绍的划时代垃圾收集器CMS(Concurrent Mark Sweep)配合使用,也是一个重要原因。
4、Parallel Scavenge收集器前面介绍的垃圾收集器关注点是尽可能缩小垃圾收集时的用户线程停顿时间。而 Parallel Scanvenge 收集器是为了达到一个可控制的吞吐量。
吞吐量 = 运行用户代码的时间 / (运行用户代码的时间+垃圾收集时间)
可以用下面两个参数进行精确控制:
-XX:MaxGCPauseMills 设置最大垃圾收集停顿时间
-XX:GCTimeRatio 设置吞吐量大小
①、作用于新生代
一个新生代垃圾收集器,采用的垃圾回收算法是复制算法。
②、多线程
并行的多线程垃圾收集器。
③、吞吐量
这个收集器可以精确控制吞吐量。
④、适用场景
设置垃圾收集停顿时间短适合需要与用户快速交互的程序;
而设置高吞吐量可以最高效的利用CPU效率,尽快的完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。
5、Serial Old收集器Serial Old 收集器是 Serial 收集器的老年代版本,特点如下:
①、作用于老年代
②、单线程
③、使用标记-整理算法
④、进行垃圾收集时,必须暂停所有工作线程
6、Parallel Old收集器Parallel Old 是 Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。
①、作用于老年代
②、多线程
③、使用标记-整理算法
除了具有以上几个特点,比较关键的是能和新生代收集器 Parallel Scavenge 配置使用,获得吞吐量最大化的效果。
7、CMS收集器CMS,全称为 Concurrent Mark Sweep ,顾名思义并发的,采用标记-清除算法。另外也将这个收集器称为并发低延迟收集器(Concurrent Low Pause Collector)