JVM - 垃圾回收器概述

4 篇文章 0 订阅
本文介绍了JVM的垃圾回收器,包括串行收集器、并行收集器和CMS收集器的工作原理和特点。串行收集器适用于单线程环境,而ParNew和ParallelGC关注系统吞吐量。CMS收集器是一款低停顿的老年代垃圾收集器,其工作流程包括初始化标记、并发标记等多个阶段。主要参数如-XX:CMSInitiatingOccupancyFraction用于配置触发CMS的阈值。
摘要由CSDN通过智能技术生成

既然选择了远方,即使天寒地冻,路遥马亡,我本就一无所有,又有何惧。

串行收集器

  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垃圾收集器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值