当前位置: 首页 > news >正文

深入解密 JVM:CMS 垃圾回收器的“并发标记”到底是不是多此一举?

深入解密 JVM:CMS 垃圾回收器的“并发标记”到底是不是多此一举?

在学习 JVM 垃圾回收机制时,很多开发者在看到 CMS (Concurrent Mark Sweep) 垃圾回收器的执行步骤图时,都会产生一个直击灵魂的疑问:

“初始标记和重新标记,不是已经把所有的存活对象都标记过了吗?为什么中间还要夹一个耗时极长的‘并发标记’?这到底有什么用?”

这是一个非常牛的观察!很多初学者都会被这几个名字给“骗”了。你之所以会产生这个巨大的逻辑冲突,是因为你严重高估了“初始标记(Initial Mark)”的工作量

直接给你纠正这个极其关键的底层误区:初始标记,根本就没有把所有的存活对象标记出来!它仅仅只标记了冰山一角。

为了让你彻底看清这三个阶段到底在干嘛,我们把整个标记存活对象的过程,拆解为“1%、98%、1%”的工作量分配比例来看。

一、 初始标记(Initial Mark):只干 1% 的活,必须 STW

  • 真相揭秘:在这个阶段,GC 线程绝对不会顺藤摸瓜去遍历整个堆内存里的所有对象。它只做极其简单的一件事:仅仅标记那些和 GC Roots 直接相连的“第一层对象”。
  • 为什么这么快:因为程序中作为 GC Roots 的对象(比如线程栈里的局部变量、静态变量)以及它们的直系子对象数量是极少的。所以,虽然这个阶段需要“暂停所有用户线程(Stop The World, STW)”,但由于工作量极小,暂停时间极其短暂,你几乎感觉不到系统的卡顿。

二、 并发标记(Concurrent Mark):干 98% 的脏活累活

  • 核心作用:这才是真正干大活的阶段!也是图示中最核心的一步。GC 线程会从刚才“初始标记”找出的第一层对象开始,顺藤摸瓜,一层一层地深度遍历整个极其庞大的对象关系引用图(可能有几十万、几百万个对象)。
  • 为什么必须“并发”:因为遍历所有的存活对象实在太耗时了!如果这个时候让系统停下来(STW)去慢慢找,你的 Java 程序可能会直接卡顿好几秒甚至几十秒,这对于 Web 应用来说是灾难性的。为了不让你觉得卡,CMS 做出了最大的让步:让 GC 线程和你的业务(用户)线程同时运行(并发)。

三、 重新标记(Remark):查漏补缺的最后 1%,必须 STW

  • 真相揭秘:既然第二步是“并发”干活的,这就意味着一个极其残酷的现实:在 GC 线程到处做标记的时候,你的业务线程还在疯狂地 new 新对象,或者修改老对象的引用关系!
  • 核心作用:经过漫长的第二步,GC 线程终于把对象图遍历完了。但因为业务线程在捣乱,导致第二步的结果不一定 100% 准确(会产生著名的“漏标”或“错标”问题)。所以,CMS 必须最后再咬牙暂停一次用户线程(STW),花极短的时间,把第二步期间发生“引用变动”的那一小撮对象,重新核对并修正一遍。

💡 终极通俗大比喻:警察抓黑帮网络

如果上面的技术原理解释还不够直观,我们来想象一个“抓出整个黑帮网络(找存活对象)”的场景:

  1. 初始标记(封锁全城 1 秒钟):警察突然行动,直接冲进几个老大的家里,把老大(GC Roots 的直系小弟)按住。因为目标明确,耗时极短。
  2. 并发标记(全城恢复正常生活,警察便衣暗访):警察根据老大的手机通讯录,顺藤摸瓜去查下面的堂主、小弟、马仔(遍历整个对象图)。这个过程可能要查好几个月,为了不引发经济瘫痪,绝对不能封锁城市,必须让市民继续正常生活(业务线程并发运行)。
  3. 重新标记(再次封锁全城 1 分钟):因为查了几个月,这期间肯定有小弟新认了大哥,或者有人退出了黑帮。为了防止抓错人或漏抓人,警察必须再短暂停顿一下城市,把这几个月内发生的“人事变动”对齐一下账本,做最后的收网确认。

总结

现在你明白了,如果没有图中的并发标记,CMS 根本找不到那剩下 98% 藏在深处的存活对象。正因为顺藤摸瓜找对象极其耗时,CMS 为了降低停顿时间(Low Pause),才让业务线程一起跑;也正因为允许业务线程一起跑,才不可避免地引出了后面那一步用于“擦屁股”和“对账”的重新标记。

允许业务线程一起跑,才不可避免地引出了后面那一步用于“擦屁股”和“对账”的重新标记。

这就是 CMS 垃圾回收器在“吞吐量”与“低延迟”之间做出的最精妙的博弈!

http://www.jsqmd.com/news/612431/

相关文章:

  • 【实战】Ubuntu 22.04LTS下Nvidia驱动安装与GCC版本冲突解决指南
  • 2026年络机柜厂家如何选?梯队式实力名录与选型指南 - 优质品牌商家
  • 万象视界灵坛参数详解:候选标签最大长度(77 tokens)与截断策略说明
  • 颠覆传统:March7thAssistant让崩坏星穹铁道自动化游戏体验提升10倍
  • 电脑风扇智能控制完全指南:从噪音困扰到静音高效的转变
  • 手机豆包怎么导出文档
  • 无需网络!Qwen2.5-VL-7B-Instruct纯本地部署与图文交互教程
  • Cadence Sigrity 模块深度解析:从电源完整性到信号优化的全流程应用
  • 7款ToB客户管理系统横评,线索到项目核心能力对比 - 毛毛鱼的夏天
  • 硅谷前沿访谈:CUDA之父复盘英伟达20年护城河,揭开万亿算力帝国的底牌
  • 3分钟搞定iPhone USB网络共享:Windows苹果驱动极简安装指南
  • Windows触控板终极优化指南:如何在Windows上实现macOS风格的三指拖拽功能
  • 储能系统弱网容灾架构设计:基于 SQLite 缓存与 MQTT 断点续传的边缘实现详解
  • 编写 dockerfile 的零散技巧
  • macOS资源下载完全指南:从入门到精通的网络资源嗅探解决方案
  • 算法岗面试避坑指南:从运动控制到ROS与PPO的实战复盘
  • 3 分钟搞定论文格式!Paperxie AI:让本科生彻底摆脱排版内耗
  • OpenClaw多模态编程:用Phi-3-vision-128k-instruct开发视觉脚本
  • 2026年4月汽车模具供应商选哪家,金属配件/冲压件/冲压模具/连续模具/航空模具/模具/汽车配件,汽车模具公司怎么选择 - 品牌推荐师
  • SiRFstarIII GPS协议解析库:二进制与NMEA双模轻量级实现
  • U盘做成系统盘以及如何恢复
  • 毕设思路
  • Kibana Dev Tools 注释全解析:从新手困惑到高效查询
  • Testsigma企业级自动化测试平台架构设计与高可用部署指南
  • Spring Boot HelloWorld 入门项目
  • 追念殡葬:甘肃专业殡葬机构如何以透明与人文重塑行业标杆 - 深度智识库
  • 期刊论文发表通关手册:PaperXie 智能写作,从选题到见刊的「开挂」指南
  • 【LeetCode】102.二叉树的层序遍历
  • 番茄小说下载器完整指南:3种方法永久保存你喜爱的小说
  • 海外华人婚恋机构可靠婚介系统推荐指南:婚恋系统搭建、相亲交友小程序、相亲小程序制作、相亲系统、红娘系统、婚介小程序选择指南 - 优质品牌商家