乐趣区

关于java:JVM-垃圾回收器概述

[toc]

既然抉择了远方,即便天寒地冻,路遥马亡,我本就赤贫如洗,又有何惧。

串行收集器

  1. 单线程、独占式进行垃圾回收
  2. 独占式:应用程序线程会进行工作,只有垃圾回收线程在工作,即 stop the world
  3. 在并行能力较差的机器上,会有更好的性能体现。

新生代串行收集器

  1. 新生代串行收集器应用的是 复制算法
  2. 应用 -XX:UseSerialGC, -XX:+UseConcMarkSweepGC -XX:-UseParNew 启用
  3. GC 日志如下所示
[GC (Allocation Failure) [DefNew: 67932K->0K(78720K), 0.0002327 secs] 68792K->859K(253504K), 0.0002491 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

老年代串行收集器

  1. 老年代串行收集器应用的是 标记 - 压缩算法
  2. 应用 -XX:UseSerialGC-XX:+UseParNewGC 启用
  3. GC 日志如下
[Full GC (Allocation Failure) [Tenured: 10250K->10249K(15360K), 0.0187416 secs] 10250K->10249K(19968K), [Metaspace: 9228K->9228K(1058816K)], 0.0187608 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

并行收集器

ParNew

  1. 新生代垃圾回收器
  2. 新生代串行收集器的多线程版本
  3. 与新生代串行收集器的区别仅在于垃圾回收时,是多线程并行。
  4. 应用 -XX:UseParNew-XX:UseConcMarkSweepGC 启用
  5. GC 日志如下
[GC (Allocation Failure) [ParNew: 82K->24K(4608K), 0.0003178 secs][Tenured: 15353K->10251K(15360K), 0.0185459 secs] 15435K->10251K(19968K), [Metaspace: 8855K->8855K(1056768K)], 0.0188925 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 

ParallelGC

  1. 新生代垃圾回收器,应用 复制算法
  2. ParNew 相比,ParallelGC 更关注吞吐量
  3. -XX:MaxGCPauseMillis:设置最大垃圾进展工夫。例:-XX:MaxGCPauseMillis=200
  4. -XX:GCTimeRatio:设置吞吐量大小。取值范畴为 0~100 的整数。若值为 n,那么 JVM 将破费不超过 1/(1+n) 的工夫在 GC 上。例:-XX:GCTimeRatio=99
  5. -XX:+UseAdaptiveSizePolicy:自适应调整 新生代大小、eden 和 survivor 比例,以及降职老年代对象年龄等参数
  6. 可通过 -XX:+UseParallelGC-XX:+UseParallelOldGC 启用
  7. GC 日志如下
[GC (Allocation Failure) [PSYoungGen: 2410K->512K(4608K)] 12650K->10947K(19968K), 0.0016662 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 

ParallelOldGC

  1. 老年代垃圾回收器,应用 标记 - 压缩算法
  2. ParallelGC 统一,关注零碎吞吐量 ParallelOldGCjdk1.6 后(包含) 才能够应用
  3. -XX:ParalleGCThreads:设置 GC 时,并行的线程数
  4. 可通过 -XX:+UseParallelGC-XX:+UseParallelOldGC 启用
  5. GC 日志如下
[Full GC (Allocation Failure) [PSYoungGen: 480K->0K(4608K)] [ParOldGen: 10499K->626K(15360K)] 10979K->626K(19968K), [Metaspace: 3063K->3063K(1056768K)], 0.0043604 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 

CMS

CMS 是一款 低进展 老年代 垃圾收集器。个别与 Serial, ParNew 新生代收集器一起工作,默认是 ParNew
工作流程细化为以下几个步骤

  1. 初始化标记(stop the world
  2. 并发标记
  3. 预清理
  4. 从新标记(stop the world
  5. 并发清理
  6. 并发重置状态期待下次 CMS 触发

初始化标记

  1. stop the world
  2. 标记老年代 GC Root 对象
  3. 标记老手代援用老年代的对象

并发标记

  1. 与利用线程 并发执行,从上一步标记的节点顺着援用链路往下标记
  2. 并发标记过程中,老年代会产生新的对象、老年代援用会变更等等。为了进步从新标记的效率,这些对象所在的 card 会被标记为 dirty
  3. 这一阶段,可能会导致 concurrent mode failure

预清理

与利用线程 并发执行 ,解决上一个阶段被标记为 dirty 的对象。该阶段为了缩小 从新标记 产生的进展工夫, 有可能 会期待一次 ygc

从新标记

  1. stop the world
  2. dirtyroot 持续往下标记可达对象

并发清理

  1. 与利用线程 并发执行
  2. 采纳 标记 - 革除 算法将垃圾革除

concurrent mode failure

在并发清理阶段,提到,有可能会产生 concurrent mode failure 景象。
呈现该景象的实质起因如下:
老年代没有足够的空间调配对象,从而导致应用 Serial Old 垃圾收集器触发一次 Full GC

主要参数

  1. -XX:ConcGCThreads, -XX:ParallelCMSThreads
    CMS 默认启动的并发线程是(ParallelGCThreads + 3)/ 4. ParallelGCThreads 示意新生代 GC 线程数量。-XX:ConcGCThreads -XX:ParallelCMSThreads 可手动指定 CMS 并发线程
  2. -XX:+CMSScavengeBeforeRemark
    在进行 从新标记 阶段时,会执行一次 ygc
  3. -XX:CMSInitiatingOccupancyFraction
    默认 68,当老年代空间使用率达到该值时,会执行一次 CMS GC
  4. -XX:+UseCMSCompactAtFullCollection
    使 CMS 在垃圾收集实现后,进行一次内存碎片整顿,碎片整顿会 stop the world
  5. -XX:CMSFullGCsBeforeCompaction
    默认 0,设定进行多少次 CMS 回收后,进行一次内存压缩
  6. -XX:CMSMaxAbortablePrecleanTime
    默认 5000 毫秒,预清理阶段,期待 ygc 最大工夫
  7. -XX:+CMSClassUnloadingEnabled
    容许回收 Class

垃圾回收器组合

笔者无奈在 jdk1.8 上,测试出 serial + parallel old 组合。

参考

CMS 垃圾收集器

退出移动版