CMS垃圾收集器——重新标记和浮动垃圾的思考
《深入理解java虚拟机 第二版 JVM高级特性与最佳实践》里面提到 CMS 垃圾收集器。
CMS 垃圾收集器的垃圾回收分4个步骤:
- 初始标记(initial mark) 有 STW
- 并发标记(concurrent mark) 没有 STW
- 重新标记(remark) 有 STW
- 并发清除(concurrent sweep) 没有 STW
初始标记:仅仅标记 GC Roots 能直接关联到的对象。
并发标记:对初始标记标记过的对象,进行 trace(进行追踪,得到所有关联的对象,进行标记)
重新标记:(原文):为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录。
CMS 垃圾收集器主要有三个问题:
- 内存碎片(原因是采用了标记-清除算法)
- 对 CPU 资源敏感(原因是并发时和用户线程一起抢占 CPU)
- 浮动垃圾:在并发标记阶段产生了新垃圾不会被及时回收,而是只能等到下一次GC
然后我产生了一个疑问:既然重新标记可以修正并发标记阶段的变动,那么为何还有浮动垃圾问题?
网上并没有找到有人对这个问题进行讨论,于是我在 Oracle 官方对 CMS 的介绍中找到了这样一句话:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html
The second pause comes at the end of the concurrent tracing phase and finds objects that were missed by the concurrent tracing due to updates by the application threads of references in an object after the CMS collector had finished tracing that object. This second pause is referred to as the remark pause.
翻译:第二次暂停是在并发跟踪阶段结束时进行的,它查找由于CMS收集器完成对对象的引用后,应用程序线程对对象中的引用进行更新而导致并发跟踪遗漏的对象。该第二暂停称为重新标记暂停。
以下是我个人对这个问题的解答猜想:
由于标记阶段是从 GC Roots 开始标记可达对象,那么在并发标记阶段可能产生两种变动:
- 本来可达的对象,变得不可达了
- 本来不可达的内存,变得可达了
第一种变动会产生所谓的浮动垃圾,第二种变动怎么回事呢?重点在于miss。
如果并发标记阶段用户线程里 new 了一个对象,而它在初始标记和并发标记中是不会能够从 GC Roots 可达的,也就是were missed。如果没有重新标记阶段来将这个对象标记为可达,那么它会在清理阶段被回收,这是严重的错误,是必须要在重新标记阶段来处理的,所以这就是重新标记阶段实际上的任务。
相比之下,浮动垃圾是可容忍的问题,而不是错误。那么为什么重新标记阶段不处理第一种变动呢?也许是由可达变为不可达这样的变化需要重新从 GC Roots 开始遍历,相当于再完成一次初始标记和并发标记的工作,这样不仅前两个阶段变成多余的,浪费了开销浪费,还会大大增加重新标记阶段的开销,所带来的暂停时间是追求低延迟的CMS所不能容忍的。
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.从而也可以推测 ...
- 实例透彻分析CMS垃圾收集器执行过程
CMS收集器收集步骤: 在上一次[https://www.cnblogs.com/webor2006/p/11055468.html]中已经对CMS的垃圾收集器有了一定的理论上的了解,其中提到了CMS ...
- 稳了!我准备了1个晚上的CMS垃圾收集器
面试官:今天还是来聊聊CMS垃圾收集器呗? 候选者:嗯啊... 候选者:如果用Seria和Parallel系列的垃圾收集器:在垃圾回收的时,用户线程都会完全停止,直至垃圾回收结束! 候选者:CMS的全 ...
- CMS垃圾收集器与G1收集器
1.CMS收集器 CMS收集器是一种以获取最短回收停顿时间为目标的收集器.基于“标记-清除”算法实现,它的运作过程如下: 1)初始标记 2)并发标记 3)重新标记 4)并发清除 初始标记.从新标记这两 ...
- CMS垃圾收集器深入详解
上一次[https://www.cnblogs.com/webor2006/p/11048407.html]对安全点和安全区进行了理论化的了解,接下来继续对CMS进行其它理论的了解,还是纯理论!!坚持 ...
- [转]使用CMS垃圾收集器产生的问题和解决方案
在之前的一篇文章<CMS vs. Parallel GC>里通过实验的方式对比了并行和并发GC的优缺点,在文章结尾提到,CMS并行GC是大多数应用的最佳选择,然而, CMS并不是完美的,在 ...
- 深入理解JVM - 垃圾收集器
垃圾回收主要是要解决3件事情: 那些内存需要回收? 如何回收? 什么时候回收? 那些内存需要回收 在强引用的情况下已经“死”了的对象就需要回收,在非强引用的情况下视情况回收.在java里面,几乎所有的 ...
- Java虚拟机垃圾回收(三) 7种垃圾收集器
Java虚拟机垃圾回收(三) 7种垃圾收集器 主要特点 应用场景 设置参数 基本运行原理 在<Java虚拟机垃圾回收(一) 基础>中了解到如何判断对象是存活还是已经死亡?在<Java ...
随机推荐
- 使用 Hexo 搭建静态博客
目录 Hexo 简介 什么是 Hexo? Hexo 安装 Hexo 建站 Hexo 配置 Hexo 自定义主题 Hexo 写作 Hexo 服务器 Hexo 生成与发布 一键部署 Hexo 站点到 gi ...
- SpringBoot实现通用的接口参数校验
本文介绍基于Spring Boot和JDK8编写一个AOP,结合自定义注解实现通用的接口参数校验. 缘由 目前参数校验常用的方法是在实体类上添加注解,但对于不同的方法,所应用的校验规则也是不一样的,例 ...
- 《Docker基础与实战,看这一篇就够了》
什么是Docker? Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术 ...
- 【Linux进阶】使用grep、find、sed以及awk进行文本操作
目录 一.元字符 二.grep命令 1. 过滤出包含某字符串的行 2. 过滤出以某字符串开头(结尾)的行 3. 过滤出包含某字符串及其相邻的行 4. 过滤出不包含某关键字的行 5. 过滤出包含多个字符 ...
- 【dp】动归总结
原标题:[DP专辑]ACM动态规划总结 转载自 http://blog.csdn.net/cc_again?viewmode=list http://blog.csdn.net/cc_again/ar ...
- Linux命令大全之搜索命令
文件搜索命令(只能搜索文件) locate 文件名 在后台数据库中按文件名搜索,搜索速度快 /var/lib/mlocate(locate文件数据库) 这个数据库默认一天更新一次,强制 ...
- Acwing Arithmetic Learning:数据结构(2)
目录 数据结构(2)acwing 1.trie树 2.并查集(近乎O(1)) 3.堆 数据结构(2)acwing 1.trie树 快速存储和查找字符串的集合 结构特征: 例题:Trie字符串统计 ? ...
- Spring Boot下的一种导出Excel文件的代码框架
1.前言 在Spring Boot项目中,将数据导出成Excel格式文件是常见的功能.与Excel文件导入类似,此处也用代码框架式的方式实现Excel文件导出,使得代码具有可重用性,并保持导出数据 ...
- 海量数据Excel报表利器——EasyExcel(开场篇)
EasyExcel 简介篇 互联网的精髓就是共享,可以共享技术.共享经验.共享情感.共享快乐~ 很多年前就有这个想法了,从事IT行业时间也不短了,应该把自己工作和业余所学习的东西记录并分享出来,和有缘 ...
- Layui 关闭自己刷新父页面
var index = parent.layer.getFrameIndex(window.name); parent.layer.close(index); window.parent.locati ...