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 ...
随机推荐
- SpringCloud+Docker+Jenkins+GitLab+Maven实现自动化构建与部署实战
1.前言与初衷 本文章会涉及Docker常见命令基础知识点结合不同场景实操一起使用. 本文章会涉及结合工作过程中部署不同环境服务器的项目案例场景为初心进行实际细讲. 本文章主要讲述Docker.Jen ...
- JMeter定时器种类+详细教程举例
首先,我们先了解一下定时器的常见种类以及它的作用. 原文地址:https://www.cnblogs.com/istart/p/11184533.html 一.定时器种类+作用 上面是我截图的自己有道 ...
- Golang编写动态库实现回调函数
Golang编写动态库实现回调函数 我们现在要做一个动态库,但是C++实在是比较难,于是就想能不能用更简单的golang来实现,golang也就是最近的版本才支持编译成动态库,在网上也没找到可用的案例 ...
- CloudCanal
CloudCanal 是一款数据迁移同步工具,帮助企业快速构建高质量数据流通通道,产品包含 SaaS 模式和私有输出专享模式.开发团队核心成员来自大厂,具备数据库内核.大规模分布式系统.云产品构建背景 ...
- hive学习笔记之五:分桶
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Spring Cloud 整合 Feign 的原理
前言 在 上篇 介绍了 Feign 的核心实现原理,在文末也提到了会再介绍其和 Spring Cloud 的整合原理,Spring 具有很强的扩展性,会把一些常用的解决方案通过 starter 的方式 ...
- Linux:Linux操作防火墙命令
首先查看Linux的防火墙是否关闭 firewall-cmd Linux上新用的防火墙软件,跟iptables差不多的工具. firewall-cmd --state # 显示防火墙状态 system ...
- Netty实现对Websocket的支持
一.WebSocket的简介及优势 WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准.WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的 ...
- MySQL参数配置
参数名称 参数说明 缺省值 最低版本要求 user 数据库用户名(用于连接数据库) 所有版本 passWord 用户密码(用于连接数据库) 所有版本 useUnicode 是否使用Unicode字符集 ...
- doc系统maven打包脚本
chcp 65001@echo off title 打包神器,龙爷造. echo ============================= echo 姓名:Long echo 日期:2020-08- ...