CMS垃圾收集器深入详解
上一次【https://www.cnblogs.com/webor2006/p/11048407.html】对安全点和安全区进行了理论化的了解,接下来继续对CMS进行其它理论的了解,还是纯理论!!坚持,因为下一次就会有实践代码了~~
CMS收集器
- CMS(Concurrent Mark Sweep)收集器,以获取最短回收停顿时间【也就是指Stop The World的停顿时间】为目标,多数应用于互联网站或者B/S系统的服务器端上。其中“Concurrent”并发是指垃圾收集的线程和用户执行的线程是可以同时执行的。
 - CMS是基于“标记-清除”算法实现的,整个过程分为4个步骤:
1、初始标记(CMS initial mark)。
2、并发标记(CMS concurrent mark)。
3、重新标记(CMS remark)。
4、并发清除(CMS concurrent sweep)。
注意:“标记”是指将存活的对象和要回收的对象都给标记出来,而“清除”是指清除掉将要回收的对象。 - 其中,初始标记、重新标记这两个步骤仍然需要“Stop The World”。
 - 初始标记只是标记一下GC Roots能直接关联到的对象,速度很快。
 - 并发标记阶段【也就说明不会阻碍业务线程继续执行,因为它所以还会有下面要说的“重新标记”阶段了】就是进行GC Roots Tracing【啥意思?其实就是从GC Roots开始找到它能引用的所有其它对象】的过程。
 - 重新标记阶段则是为了修正并发标记期间因用户程序继续动作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。
 - CMS收集器的动作步骤如下图所示,在整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,因此,从总体上看,CMS收集器的内存回收过程是与用户线程一起并发执行的:
下面对这个图做一个简要的解读:






这个“重置线程"并没有体现在之前的4个步骤当中,这个在之后会说的,对于这张图的理解可以很好的理解CMS的几个步骤。
 - 优点:并发收集、低停顿【注意:这里的停顿指的是停止用户线程】,Oracle公司的一些官方文档中也称之为并发低停顿收集器(Concurrent Low Pause Collector)。
 - 缺点:
1、CMS收集器对CPU资源非常敏感。
2、CMS收集器无法处理浮动垃圾(Floating Garbage,就是指在之前判断该对象不是垃圾,由于用户线程同时也是在运行过程中的,所以会导致判断不准确的, 可能在判断完成之后在清除之前这个对像已经变成了垃圾对象,所以有可能本该此垃圾被回收但是没有被回收,只能等待下一次GC再将该对象回收,所以这种对像就是浮动垃圾),可能出现“Concurrent Mode Failure”失败而导致另一次Full GC的产生。如果在应用中老年代增长不是太快,可能适当调高参数-XX:CMSInitiatingOccupancyFraction的值来提高触发百分比,以便降低内存回收次数从而获取更好的性能。要是CMS运行期间预留的内存无法满足程序需要时,虚拟机将启动后备预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样停顿时间就很长了。所以说参数-XX:CMSInitiatingOccupancyFraction设置得太高很容易导致大量“Concurrent Mode Failure”失败,性能反而降低。
3、收集结束时会有大量空间碎片产生,空间碎片过多时,将会给大对象分配带来很大麻烦,往往出现老年代还有很大空间剩余,但是无法找到足够大的连续空间来分配当前对象,不得不提前进行一次Full GC。CMS收集器提供了一个-XX:+UseCMSCompactAtFullCollection开关参数(默认就是开启的),用于在CMS收集器顶不住要进行Full GC时开启内存碎片的合并整理过程,内存整理的过程是无法并发的,空间碎片问题没有了,但停顿时间不得不变长。 
空间分配担保:
在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。当大量对象在Minor GC后仍然存活,就需要老年代进行空间分配担保,把Survivor无法容纳的对象直接进入老年代。如果老年代判断到剩余空间不足(根据以往每一次回收晋升到老年代对象空间的平均值作为经验值),则进行一次Full GC。
CMS收集器收集完整步骤:
- Phase1 :Initial Mark【初始标记】
 - Phase2 : Concurrent Mark 【并发标记】
 - Phase3 : Concurrent Preclean【并发预先清除】
 - Phase4 : Concurrent Abortable Preclean【并发可能失败的预先清除】
 - Phase5 : Final Remark【最终重新标记】
 - Phase6 : Concurrent Sweep【并发清除】
 - Phase7 : Concurrent Reset【并发重置】
 
以上这些过程在下次会详细进行学习,先有个了解。
CMS垃圾收集器深入详解的更多相关文章
- G1垃圾收集器和CMS垃圾收集器 (http://mm.fancymore.com/reading/G1-CMS%E5%9E%83%E5%9C%BE%E7%AE%97%E6%B3%95.html#toc_8)
		
参考来源 JVM 体系架构 堆/栈的内存分配 静态和非静态方法的内存分配 CMS 回收算法 应用场景 CMS 垃圾收集阶段划分(Collection Phases) CMS什么时候启动 CMS缺点 G ...
 - CMS垃圾收集器
		
介绍 CMS垃圾回收器的全称是Concurrent Mark-Sweep Collector,从名字上可以看出两点,一个是使用的是并发收集,第二个是使用的收集算法是Mark-Sweep.从而也可以推测 ...
 - 系统批量运维管理器Fabric详解
		
系统批量运维管理器Fabric详解 Fabrici 是基于python现实的SSH命令行工具,简化了SSH的应用程序部署及系统管理任务,它提供了系统基础的操作组件,可以实现本地或远程shell命令,包 ...
 - GridBagLayout布局管理器应用详解
		
http://www.cnblogs.com/kungfupanda/p/7220217.html GridBagLayout布局管理器应用详解 很多情况下,我们已经不需要通过编写代码来实现一个应用程 ...
 - 实例透彻分析CMS垃圾收集器执行过程
		
CMS收集器收集步骤: 在上一次[https://www.cnblogs.com/webor2006/p/11055468.html]中已经对CMS的垃圾收集器有了一定的理论上的了解,其中提到了CMS ...
 - java8学习之收集器用法详解与多级分组和分区
		
收集器用法详解: 在上次已经系统的阅读了Collector收集器的Javadoc对它已经有一个比较详细的认知了,但是!!!它毕境是只是一个接口,要使用的话还得用它的实现类,所以在Java8中有它进行了 ...
 - ffmpeg播放器实现详解 - 视频显示
		
ffplay是ffmpeg源码中一个自带的开源播放器实例,同时支持本地视频文件的播放以及在线流媒体播放,功能非常强大. FFplay: FFplay is a very simple and port ...
 - CMS垃圾收集器——重新标记和浮动垃圾的思考
		
<深入理解java虚拟机 第二版 JVM高级特性与最佳实践>里面提到 CMS 垃圾收集器. CMS 垃圾收集器的垃圾回收分4个步骤: 初始标记(initial mark) 有 STW 并发 ...
 - 稳了!我准备了1个晚上的CMS垃圾收集器
		
面试官:今天还是来聊聊CMS垃圾收集器呗? 候选者:嗯啊... 候选者:如果用Seria和Parallel系列的垃圾收集器:在垃圾回收的时,用户线程都会完全停止,直至垃圾回收结束! 候选者:CMS的全 ...
 
随机推荐
- Python equivalent of D3.js
			
http://brandonrose.org/ Python equivalent of D3.js Ask Question Asked 7 years, 1 month ago Act ...
 - 【香甜的黄油 Sweet Butter】
			
[香甜的黄油 Sweet Butter] 洛谷P1828 https://www.luogu.org/problemnew/show/P1828 JDOJ 1803 https://neooj.com ...
 - django 报错Reverse for 'detail' with keyword arguments '{'pk': '2'}' not found. 1 pattern(s) tried: ['$post/(?P<pk>[0-9]+)/$']
			
Django报错:Reverse for 'detail' with keyword arguments '{'pk': '2'}' not found. 1 pattern(s) tried: [' ...
 - 【2019.8.11上午 慈溪模拟赛 T3】欢迎回来(back)(设阈值+莫队)
			
设阈值 考虑对于询问的\(d\)设阈值进行分别处理. 对于\(d\le\sqrt{max\ d}\)的询问,我们可以\(O(n\sqrt{max\ d})\)预处理答案,\(O(1)\)输出. 对于\ ...
 - 【BZOJ3876】[AHOI2014&JSOI2014] 支线剧情(无源汇有上下界网络流)
			
点此看题面 大致题意: 有一张\(DAG\),经过每条边有一定时间,从\(1\)号点出发,随时可以返回\(1\)号点,求经过所有边的最短时间. 无源汇有上下界网络流 这是无源汇有上下界网络流的板子题. ...
 - 【BZOJ4556】[TJOI2016&HEOI2016] 字符串(后缀自动机+线段树合并+二分)
			
点此看题面 大致题意: 给你一个字符串\(s\),每次问你一个子串\(s[a..b]\)的所有子串和\(s[c..d]\)的最长公共前缀. 二分 首先我们可以发现一个简单性质,即要求最长公共前缀,则我 ...
 - 小白专场-堆中的路径-c语言实现
			
目录 一.题意理解 二.堆的表示及其操作 三.主程序 更新.更全的<数据结构与算法>的更新网站,更有python.go.人工智能教学等着你:https://www.cnblogs.com/ ...
 - vue使用--saas的引入与使用
			
什么是saas.scss? saas是一种动态样式语言,属于CSS预处理器,为CSS增加了一些编程特性,比如变量.嵌套.函数.继承.运算等等.开发人员可以像使用js等语言一样使用saas进行css的 ...
 - 如何编写一个 SendFile 服务器
			
如何编写一个 SendFile 服务器 前言 之前讨论零拷贝的时候,我们知道,两台机器之间传输文件,最快的方式就是 send file,众所周知,在 Java 中,该技术对应的则是 FileChann ...
 - .NET Core 中间件之压缩、缓存
			
前言 今天给大家介绍一下在 ASP.NET Core 日常开发中用的比较多的两个中间件,它们都是出自于微软的 ASP.NET 团队,他们分别是Microsoft.AspNetCore.Response ...