JVM 八股9 - 垃圾收集2 (STW + 垃圾收集算法)
约 466 字大约 2 分钟
STW
"Stop The World"是 Java 垃圾收集中的一个重要概念。在垃圾收集过程中,JVM 会暂停所有的用户线程,这种暂停被称为"Stop The World"事件
这么做的主要原因是为了防止在垃圾收集过程中,用户线程修改了堆中的对象,导致垃圾收集器无法准确地收集垃圾
值得注意的是,"Stop The World"事件会对 Java 应用的性能产生影响
如果停顿时间过长,就会导致应用的响应时间变长,对于对实时性要求较高的应用,如交易系统、游戏服务器等,这种情况是不能接受的。
因此,在选择和调优垃圾收集器时,需要考虑其停顿时间。Java 中的一些垃圾收集器,如 G1 和 ZGC,都会尽可能地减少了"Stop The World"的时间,通过并发的垃圾收集,提高应用的响应性能。
总的来说,"Stop The World"是 Java 垃圾收集中必须面对的一个挑战,其目标是在保证内存的有效利用和应用的响应性能之间找到一个平衡。
┌────────────────────────────────────────────────────────┐
│ GC 开始时 │
├────────────────────────────────────────────────────────┤
│ │
│ 1. 暂停所有线程 │
│ │
│ 2. 扫描所有线程栈 │
│ ┌─────────┐ │
│ │ 线程1栈 │ → 找到所有局部变量、参数 → 标记为 GC Root │
│ │ 线程2栈 │ │
│ │ ... │ │
│ └─────────┘ │
│ │
│ 3. 扫描元空间 │
│ ┌─────────────────┐ │
│ │ 类的静态变量 │ → 标记为 GC Root │
│ │ 运行时常量池常量 │ → 标记为 GC Root │
│ └─────────────────┘ │
│ │
│ 4. 从 GC Root 开始遍历引用链 │
│ GC Root → 对象A → 对象B → 对象C │
│ ↘ 对象D → 对象E │
│ │
│ 5. 标记所有可达对象 = 存活 │
│ 未被标记的对象 = 垃圾 │
│ │
└────────────────────────────────────────────────────────┘
