1. 垃圾判定机制:如何识别无用对象?
引用计数法(Reference Counting)
工作机制:每当一个对象被引用时,其引用计数加1;引用失效则减1;当计数值归零时,该对象被视为可回收垃圾。
局限性:无法处理循环引用问题。例如,对象A引用对象B,同时B也引用A,即使二者已不再被外部使用,计数也不为零,导致内存无法释放,从而引发内存泄漏。
[此处为图片1]
可达性分析(Reachability Analysis)
核心思想:以一系列被称为 GC Roots 的对象(如正在执行的线程栈中的局部变量、类的静态字段等)为起点,进行图遍历。
判定标准:所有无法通过引用链追溯到的对象,即“不可达”对象,将被标记为垃圾并准备回收。
[此处为图片2]
2. 内存区域划分:基于生命周期的分代管理
JVM 根据大多数对象“朝生夕死”的统计规律,采用分代设计对堆内存进行逻辑划分,提升回收效率。
年轻代(Young Generation)
用途:用于存放新创建的对象。
特性:对象存活率非常低,大部分在一次GC后即被清理。
回收策略:采用复制算法(Copying),仅将少数存活对象复制到幸存者区(Survivor),实现高效清理。虽然会暂时占用额外空间,但适合高淘汰率场景。
老年代(Old Generation)
用途:存储经历过多次年轻代GC仍存活下来的对象。
特性:对象整体存活率较高,回收频率较低但每次涉及数据量大。
回收方式:使用标记-整理(Mark-Compact)算法,先标记存活对象,再将其集中移动至一端,有效避免内存碎片化问题。
[此处为图片3]
3. 垃圾收集器的发展:从暂停到并发
Stop-The-World(STW)现象
几乎所有GC操作都会触发短暂的全局暂停——在此期间所有应用线程停止运行,造成系统“卡顿”。优化目标之一便是尽可能缩短STW时间。
G1 收集器(Garbage First)
结构设计:将堆划分为多个大小相等的独立区域(Region),不再强制区分年轻/老年代物理位置。
调度策略:支持设定最大停顿时间目标(如200ms),优先回收垃圾比例最高的Region,兼顾响应速度与吞吐表现。
ZGC(Z Garbage Collector)——面向未来的低延迟方案
核心优势:实现并发回收,即GC线程与用户线程并行执行,极大减少停顿。
性能代价:需要更多CPU资源参与GC过程,略微影响整体吞吐量,但换来的是极低的停顿时间——通常控制在1毫秒以内,适用于对延迟极度敏感的应用场景。