GC参数介绍
总阅读次
文章目录
GC参数介绍
在本文中将介绍 串行收集器 、并行收集器 、CMS收集器 还会有一个tomcat的实例演示
串行收集器
串行收集器的特点:
- 最古老、最稳定
- 效率高
- 可能会产生较长的停顿
- -XX:+UseSerialGC
- 新生代、老年代使用串行回收
- 新生代复制算法
- 老年代标记-压缩算法
串行GC运行流程和GC日志:
新生代GC日志:
|
|
老年代GC日志:
|
|
并行收集器
ParNew
新生代并行收集,老年代还是串行,通过 -XX:+UseParNewGC
指定使用。在新生代还是使用复制算法,需要多核支持。通过 -XX:ParallelGCThreads
限制线程数量
新生代GC日志
|
|
老年代和Serial收集器一样
Parallel收集器
- 类似于ParNew
- 新生代 复制算法
- 老年代 标记-压缩法
- 更加关注吞吐量
- -XX:+UseParallelGC
- 使用Parallel收集器+老年代串行
- -XX:+UseParallelOldGC
- 使用Parallel收集器+老年代并行
Parallel收集器示例图:
GC日志示例:
|
|
并行收集器运行参数控制
- -XX:MaxGCPauseMills
- 最大停顿时间,单位毫秒
- GC尽力保证回收时间不超过设定值
- -XX:GCTimeRatio
- 0-100的取值范围
- 垃圾收集时间占总时间的比
- 默认99,即最大允许1%时间做GC
- 这两个参数是矛盾的。因为停顿时间和吞吐量不可能同时调优
CMS收集器
CMS(Concurrent Mark Sweep)收集器,并发(与用户线程一起执行)标记清除
- 使用标记-清除算法
- 并发阶段会降低吞吐量
- 老年代收集器(新生代使用ParNew)
- -XX:+UseConcMarkSweepGC
CMS运行过程比较复杂,着重实现了标记的过程,具体分为:
- 初始标记(独占CPU)
- 该阶段仅仅只是标记一下GC Roots能直接关联到的对象。
- 速度快
- 并发标记(和用户线程一起)
- 并发标记阶段就是进行GC Roots Tracing 的过程
- 重新标记(独占CPU)
- 重新标记阶段是为了修正并发标记期间因用户程序继续运行导致标记产生变动的那一部分对象的标记记录
- 该阶段停止时间一般比初识标记长些,但远比并发标记时间短
- 并发清除(和用户线程一起)
- 基于标记结果,直接清理对象
CMS收集器图例:
从上面的图例可以看出,CMS收集器器也不是绝对的不暂停用户线程,在某些阶段还是需要暂停用户线程的,比如在初始化标记和重新标记阶段,用户线程是暂停的。CMS使用的是标记-清除算法,这是没有使用标记-压缩算法是因为清理的阶段是和用户线程一起执行的。
CMSGC日志
|
|
通过上面的GC日志可以看出该次执行,发生了两次Full GC,主要关注:
- CMS-initial-mark 初始标记
- CMS-concurrent-mark 并发标记
- CMS-remark 重新标记
- CMS-concurrent-sweep 并发清理
和上面介绍的CMS流程一致
CMS收集器缺点
- CMS收集器对CPU资源非常敏感。
- CMS收集器无法处理浮动垃圾。由于CMS并发清理阶段用户线程还在运行着,伴随程序运行必然会有新的垃圾对象产生,这一部分垃圾因为在标记过程之后,CMS无法在当次收集中处理掉它们,只好留到下次GC时清理,这一部分垃圾就是浮动垃圾
- CMS收集因为是基于“标记-清除”算法,会产生大量碎片
CMS收集器内存碎片问题
因为CMS收集器使用标记-清除算法,必然会导致出现内存碎片问题。如果不进行内存碎片整理,则无法放置较大对象。为了解决该问题,CMS收集器提供了如下参数进行调控:
- -XX:+UseCMSCompactAtFullCollection
- Full GC后进行一次碎片整理,整理过程是独占的,会引起停顿时间变长
- -XX:+CMSFullGCsBeforeCompaction
- 设置进行几次Full GC后,进行一次碎片整理
- -XX:ParallelCMSThreads
- 设置CMS的线程数量