发布于2026-07-08 阅读(0)
扫一扫,手机访问
先说说最核心的认知:JVM的垃圾回收标记算法,绝不是一套固定的、孤立的技术组合。它的底层逻辑,始终围绕着可达性分析展开;它的并发能力,建立在三色标记的状态机之上;它的安全性,依赖写屏障和读屏障来兜底;而它的演进路径,则清晰指向从分代模型向区域化管理的迁移。这套机制每一次升级,实际上都在重新定义GC的停顿边界和可用性上限。

从一次性全量扫描,到支持并发标记的三色模型,再到面向大堆和亚毫秒级延迟的硬件辅助设计——标记方式的每一次跃迁,都绕不开一个根本问题:如何在准确识别存活对象的同时,把对应用线程的干扰降到最低。
所有现代JVM的标记算法,起点都是“可达性分析”,而不是引用计数。原因很简单:引用计数处理不了循环引用。算法从GC Roots出发——也就是线程栈帧中的局部变量、静态字段、JNI引用等——沿着引用链向外遍历。只要能顺着某条路径从Roots到达,对象就算存活;否则就是垃圾。这个原则从JDK 1.0起就没变过,真正在不断进化的,是“怎么遍历”以及“什么时候遍历”。
传统的标记-清除算法要求全程STW,而三色标记通过引入中间状态,把标记拆解成可暂停、可恢复的增量步骤:
标记启动时,所有Roots直接引用的对象先入灰;接着灰对象出队,把它引用的对象入灰,自身转黑;直到灰集为空,标记结束。问题在于,应用线程和GC线程并发运行时,对象引用关系可能随时变化——如果黑色对象直接指向了一个白色对象,就会造成漏标。CMS用写屏障(Incremental Update)来处理新增引用,把目标对象重新标灰;G1则使用SATB(Snapshot-At-The-Beginning),在删除引用前先记录快照,确保不漏掉任何存活对象。
三色标记本身不解决并发修改的问题,真正让它落地的,是配套的屏障机制:
这些屏障让标记不再依赖全局暂停,而是把一致性维护下沉到单次内存操作的粒度。这才是现代低延迟GC真正站稳脚跟的关键。
早期的Serial、Parallel GC,对整个年轻代或老年代做统一标记。在堆比较小的时候问题不大,但随着堆增大,效率明显下降。G1引入Region概念,把堆划分为固定大小的块(1–32MB),标记阶段只追踪跨Region的引用(通过Remembered Set),然后优先标记垃圾最多的Region。ZGC更进一步,按页(Page)组织堆,结合着色指针实现几乎无成本的并发标记——它不维护传统的标记位数组,而是通过指针颜色直接反映对象状态。标记过程本质上是遍历Root并翻转相关指针颜色,完全不需要额外的标记空间。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8