当前位置:网站首页>CMS垃圾收集器
CMS垃圾收集器
2020-11-08 20:13:00 【入门小站】
CMS垃圾收集器收集详细步骤
- 初始标记(Stop the world)
- 并发标记
- 预清理
- 可被终止的预清理
- 重新标记(Stop the world)
- 并发清除
- 并发重置
初始标记
> 标记GcRoots直接可达老年对象,新生代存活对象引用的老年代对象.整个过程在JDK1.7中是单线程的在JDK1.8中是多线程的(通过CMSParallelInitialMarkEnabled参数调整)。这个过程会导致STW。
并发标记
> 从初始标记
阶段标记过的对象开始,标记其它存活对象,这个阶段垃圾回收线程和应用线程同时运行。由于是同时运行,应用线程还在跑,会导致对象的晋升,对象引用的变化,特殊对象直接分配到老年代。这些受到影响的老年代对象所在的Card会被标记成Dirty,用于重新标记阶段扫描,老年代对象的Card被标记为Dirty的可能原因如下面绿线所示。
预清理
> 由于上一个阶段是并发执行的未标记的变化对象只是标记成了Dirty对象,还没有处理,预清理
就是来标记这些Dirty对象
。如下图:在并发标记阶段3号Card被标志为Dirty。这个阶段是为重新标记
阶段做准备。
预清理将6号标志为存活对象
可被终止的预清理
> 这个阶段也是为重新标志阶段做准备,在进入重新标志阶段前,最好能进行一个Minor GC,将年轻代清理一遍, 这样可以清除大部分年轻代的对象(绝大部分年轻代对象朝生夕死),尽量缩短重新标记
阶段停顿时间,CMS还提供了CMSScavengeBeforeRemark参数,可以在进入重新标记之前强制进行依次Minor gc。
重新标志(remark)
> 预清理
和可被终止的预清理
都是为重新标志
阶段做准备,由于重新标志
阶段会发生(STW),所以要保证尽肯能的停顿时间段,不然就会影响应用程序的用户体验。这个阶段扫描的目标是:年轻代+GC Roots+Dirty老年代对象,这个阶段是多线程的(XX:+CMSParallelRemarkEnabled)。
并发清除
> 用户线程被激活,那些未被标志的对象会被清除。'
并发重置
> CMS垃圾收集器参数回到初始状态,为下一次垃圾收集做准备。
使用CMS垃圾收集器要注意的问题
重新标记
停顿时间过长
> 80%的时间花在重新标志
阶段,如果发现重新标志
阶段停顿时间过长,可尝试添加-XX:+CMSScavengeBeforeRemark
,在重新标志
之前做一次Minor GC
,目的是减少对老年代对象的无效引用,降低重新标志
的开销。
内存碎片问题
> CMS是基于标记-清除算法的,CMS只会删除垃圾对象,不会对内存空间做压缩,会造成内存碎片。我们需要用 -XX:CMSFullGCsBeforeCompaction=n
参数来调整,含义是在上一次CMS并发执行过后,还要执行多少次Full GC
才做内存压缩.
concurrent mode failure
> 在CMS GC过程中由于应用程序也在跑,当年轻代满了,执行了Minor GC
这时候,需要将存活对象放入老年代,而此时老年代空间也不足,这时CMS还没有机会回收老年代。可以设置以下两个参数
- -XX:CMSInitiatingOccupancyFraction=75
> CMS对内存的占用率达到75%将启动GC,默认为92%,太高将导致promotion failed
- -XX:+UseCMSInitiatingOccupancyOnly
> 如果没有设置UseCMSInitiatingOccupancyOnly
,只设置了CMSInitiatingOccupancyFraction
那么JVM只在第一次使用,后续会进行自动调整。
> 为什么要设置以上两个参数,在垃圾收集阶段,用户线程还在运行,所以必须要留够空间让用户线程运行。CMS前五个阶段都是标记存活对象的,除了”初始标记”和”重新标记”阶段会stop the word ,其它三个阶段都是与用户线程一起跑的,就会出现这样的情况gc线程正在标记存活对象,用户线程同时向老年代提升新的对象,清理工作还没有开始,old gen已经没有空间容纳更多对象了,这时候就会导致concurrent mode failure, 然后就会使用串行收集器回收老年代的垃圾,导致停顿的时间非常长。 CMSInitiatingOccupancyFraction参数要设置一个合理的值,设置大了,会增加concurrent mode failure发生的频率,设置的小了,又会增加CMS频率,所以要根据应用的运行情况来选取一个合理的值。如果发现这两个参数设置大了会导致full gc,设置小了会导致频繁的CMS GC,说明你的老年代空间过小,应该增加老年代空间的大小了。
promotion failed
> 在进行Minor GC时,Survivor space放不下,对象只能放入老年代,而此时老年代也放不下,大多数情况是老年代内存碎片太多,导致没有连续的空间存放对象。
过早的晋升和晋升失败
> 发生Minor GC时,如果对象过大(Survivor Space存放不下)基本上会放到老年代,这种现象被称为对象过早晋升,这将导致老年代被中短期对象增张,肯能导致严重的性能问题。如果老年代也满了,会触发Full GC,这将会导致遍历整个堆,晋升失败。
解决方案
- 如果是因为内存碎片导致的大对象提升失败,cms需要进行空间整理压缩;
- 如果是因为提升过快导致的,说明Survivor 空闲空间不足,那么可以尝试调大 Survivor;
- 如果是因为老年代空间不够导致的,尝试将CMS触发的阈值调低。
CMS总结
- CMS只收集老年代,响应速度优先。
- 重新标记会STW,停顿时间较长,所以在这之前进行一次Minor GC,会减少很多对老年代对象的无效引用。
- 内存碎片问题导致的Full GC,请使用
-XX:CMSFullGCsBeforeCompaction=n
,有规律对内存进行整理减少内存碎片。 - JDK1.7,JDK1.8设置CMS垃圾收集器
XX:+UseConcMarkSweepGC
几个重要的CMS参数
-XX:CMSFullGCsBeforeCompaction=n
Full GC
n 次后进行内存压缩整理-XX:CMSInitiatingOccupancyFraction=70
-XX:+UseCMSInitiatingOccupancyOnly
内存占用70%将触发CMS GC
-XX:+CMSScavengeBeforeRemark
CMS GC前执行一次Minor GC
版权声明
本文为[入门小站]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4232146/blog/4708332
边栏推荐
- IT industry salary has been far ahead! Ten years later, is the programmer still a high paying profession?
- getBytes之 LengthFieldBasedFrameDecoder服务端解析
- Your random IO hard disk
- Django之简易用户系统(3)
- 【Elasticsearch 技术分享】—— 十张图带大家看懂 ES 原理 !明白为什么说:ES 是准实时的!
- 动态规划设计:最大子数组
- Using k3s to create local development cluster
- 选择排序
- Development and deployment of image classifier application with fastai
- 单例模式的五种设计方案
猜你喜欢
Is parameter passing in go language transfer value or reference?
[cloud service] there are so many ECS instances on alicloud server, how to select the type? Best practice note
Python 列表的11个重要操作
快来看看!AQS 和 CountDownLatch 有怎么样的关系?
What is forsage Ethereum smart contract? What is the global decline of Ethereum
Using fastai to develop and deploy image classifier application
【Elasticsearch 技术分享】—— 十张图带大家看懂 ES 原理 !明白为什么说:ES 是准实时的!
Introduction and application of swagger
Creating a text cloud or label cloud in Python
如果把编程语言当武功绝学!C++是九阴真经,那程序员呢?
随机推荐
如果把编程语言当武功绝学!C++是九阴真经,那程序员呢?
线程池运用不当的一次线上事故
go语言参数传递到底是传值还是传引用?
Why need to use API management platform
PAT_甲级_1056 Mice and Rice
使用基于GAN的过采样技术提高非平衡COVID-19死亡率预测的模型准确性
在Python中创建文字云或标签云
TypeScript(1-2-2)
Summary of interface test case ideas
Not a programmer, code can't be too ugly! The official writing standard of Python: pep8 everyone should know
latex入门
Suffix expression to infix expression
git操作与分支管理规范
Django's simple user system (3)
The interface testing tool eolinker makes post request
寻找性能更优秀的不可变小字典
不是程序员,代码也不能太丑!python官方书写规范:任何人都该了解的 pep8
经典动态规划:最长公共子序列
【Elasticsearch 技术分享】—— 十张图带大家看懂 ES 原理 !明白为什么说:ES 是准实时的!
IT行业薪资一直遥遥领先!十年后的程序员,是否还是一个高薪职业?