垃圾收集器

  垃圾收集算法是垃圾回收的理论,那么垃圾收集器是垃圾回收的具体实现。不同的版本、不同厂商的虚拟机所提供的垃圾收集器可能差别很大,一般的话根据自己的应用特点和要求组合出不同年代所使用的垃圾收集器。

  • Serial 收集器
  • ParNew 收集器
  • Parallel Scavenge收集器
  • Serial Old收集器
  • Parallel Old 收集器
  • CMS
  • G1

Serial 收集器
    Serial收集器是单线程收集器,不仅仅是指只有一个CPU或者一条线程是执行垃圾收集工作,而且Serial收集器执行的时候,会暂停其他所有的工作线程(stop the world),直到收集完毕。(在jdk1.3之前是新生代唯一的选择),属于新生代收集器。
    其实到目前为止,它仍然是虚拟机运行在Client模式下默认的新生代收集器(优点:简单高效),因为在收集几十兆甚至一两百兆的新生代,停顿的时间很短(几十毫秒)。
ParNew 收集器
    ParNew收集器是Serial收集器的多线程版本,除了使用多条线程收集之外,其他的行为和Serial一样。属于新生代收集器。
    ParNew收集器是运行在Server模式下虚拟机首选的新生代收集器。除了使用多线程高效以外,更重要的是因为除了Serial收集器外,只有它能与CMS收集器配合使用

 

Parallel Scavenge收集器
    Parallel Scavenge收集器属于新生代收集器,采用复制算法,是一个并行的的多线程收集器。看起来和ParNew一样,Parallel Scavenge 特点:ParNew 、CMS 收集器的关注点在于缩短垃圾回收时用户工作线程的暂停时间,但是 Parallel Scavenge关注的是达到一个可控制的吞吐量(运行用户代码时间/运行代码时间+垃圾收集消耗时间),停顿时间越短越适合与客户交互的程序,而吞吐量高可以高效的利用CPU的时间,尽快完成程序的运算任务,更适合后台运算而不需要太多交互任务的程序。
Parallel Scavenge收集器参数控制
  • -XX:MaxGCPauseMillis:
  • -XX:GCTimeRatio
  • -XX:+UseAdaptiveSizePolicy
XX:MaxGCPauseMillis:最大垃圾收集停顿时间,大于0的毫秒数(并不是设置越小越好,GC停顿时间的缩短牺牲吞吐量和新生代空间换取的,新生代空间变小了,垃圾收集的频率就加快了,这样停顿的次数也增加了,吞吐量也会降下来)。
-XX:GCTimeRatio:设置吞吐量大小,大于0小于100的值,吞吐量大小。(例如设置为19,则最大的GC时间为5% 1/(1+19),默认是99,就是允许最大 1% 1/(1+99))。
-XX:+UseAdaptiveSizePolicy:GC自适应调节策略开关。
 
 
Serial Old收集器
    Serial Old收集器是Serial 收集器 老年代的版本,也是单线程收集器,使用 "标记-整理" 算法。主要意义也是被Client模式下使用,在Server模式下,主要有2个用途:
  •     在jdk1.5以及以前版本,搭配Parallel Scavenge 收集器搭配一起使用
  •     作为CMS收集器的备选预案
Parallel Old 收集器
    Parallel Old收集器是Parallel Scavenge 收集器的老年代版本,使用多线程 和 "标记-整理" 算法
CMS 收集器(并发标记清除收集器)
    CMS(Concurrent Mark Sweep)收集器,采用 "标记-清除" 算法,属于老年代收集器。是一种以获取最短停顿时间为目标的收集器。适用于交互响应速度快的应用。
    CMS收集器整个过程分为4个步骤:
  • 初始标记(CMS initial mark)
  • 并发标记(CMS concurrent mark)
  • 重新标记(CMS remark)
  • 并发清除
    初始标记:标记下GC Roots能直接关联的对象,初始标记需要暂停所有工作线程
    并发标记:进行 GC Roots  Tracing的标记过程
    重新标记:标记那些在并发标记过程中,其他工作线程继续工作产生的部分对象,重新标记需要暂停所有工作线程
    并发清除:清除工作和用户线程并行执行。
    初始标记和重新标记阶段需要暂停用户线程。并发标记和并发清除阶段可以和用户线程并行工作,因此消耗的时间最长。
 
 
G1收集器
  G1收集器与CMS收集器比较有两个显著的改进:G1基于 "标记-整理" 算法,就是说不会产生内存"碎片",对于长时间运行的系统非常重要,另外就是G1收集器可以精确的控制停顿时间,可以让使用者明确执行在M毫秒时间段内消耗的在收集垃圾的时间不超过N毫秒。
  G1收集器可以在不牺牲吞吐量的前提下完成低停顿的垃圾回收,因为前面的垃圾收集器收集的范围是整个新生代或者老年代,而G1收集器是将整个Java堆(包括新生代和老年代)划分成多个大小固定的独立区域(region),并且跟踪region内的垃圾堆积程度,后台维护一个优先列表,优先收集垃圾最多的区域(garbage first),保证有限的时间内可以获得最高的收集效率。
 
 
参考:《深入理解Java虚拟机:JVM高级特性与实践》
原文地址:https://www.cnblogs.com/xiaojianfeng/p/9367756.html