JVM垃圾回收无法用纯Java完全复现,但可简化模拟可达性分析、标记-清除流程及软/弱引用行为:通过DFS遍历对象图标记存活对象,逻辑清除未标记对象,并利用SoftReference/WeakReference验证回收时机。

JVM 垃圾回收机制本身由 HotSpot 虚拟机底层用 C++ 实现,不能用纯 Java 完全复现其并发、精确停顿、分代移动等真实行为。但可以通过简化模型,在 Java 中模拟核心逻辑:对象可达性判定、标记过程、回收动作和内存状态变化。重点不是“替代 JVM”,而是帮助理解“谁是垃圾”“怎么标记”“回收后内存如何变化”这三个关键环节。
模拟可达性分析(谁是垃圾)
真实 JVM 以 GC Roots(如栈变量、静态字段)为起点遍历引用链。我们可用一个简易图结构 + DFS 模拟:
- 定义 Node 类,含
name和List<Node> refs表示引用关系 - 手动构造 GC Roots(比如一个全局
root变量),再构建对象图(如 A→B、B→C、D 孤立) - 用递归或栈实现 DFS 遍历,将所有从 root 出发可达的对象标记为
isAlive = true - 遍历结束后,
isAlive == false的对象即为“可回收垃圾”
模拟标记-清除流程(怎么回收)
这是最易理解的算法,适合教学模拟:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 先执行上述可达性分析,完成“标记”阶段
- 在“清除”阶段,遍历所有已创建对象(比如维护一个全局
List<Node> heap),对未标记对象执行clear()(如置空字段、设data = null) - 可额外统计“回收数量”和“剩余存活数”,打印日志模拟 GC 日志输出
- 注意:不真正释放 JVM 堆内存(Java 无法手动释放),而是逻辑上移出活跃集合,体现“不再被程序使用”语义
模拟软/弱引用行为(非强引用场景)
Java 提供了 SoftReference 和 WeakReference,可直接用于代码验证其回收时机:
- 创建
SoftReference<byte[]> soft = new SoftReference<>(new byte[1024*1024]);,然后主动触发System.gc()并观察soft.get()是否为null(通常在内存紧张时才回收) - 创建
WeakReference<String> weak = new WeakReference<>(new String("test"));,紧接着调用System.gc(),几乎立刻返回null—— 这就模拟了弱引用“下次 GC 就收”的特性 - 这类模拟无需自建算法,直接利用 JDK 原生能力,是最贴近真实行为的验证方式
附加:触发与观察 GC 的实用技巧
虽然不能控制 JVM 真实 GC 时间点,但可通过以下方式辅助验证模拟逻辑:
- 启动参数加
-XX:+PrintGCDetails -Xloggc:gc.log,让 JVM 输出真实 GC 日志,与你的模拟结果对照(例如某次 Minor GC 回收了多少对象) - 用
Runtime.getRuntime().totalMemory()和.freeMemory()计算已用内存,配合System.gc()观察内存波动(注意:System.gc()是建议,不保证立即执行) - 避免在模拟中调用
finalize()—— 它已被弃用,且行为不可靠,现代 GC 不依赖它

















