likes
comments
collection
share

JVM中的“白金之星”:超详细STW(Stop-The-World)解析

作者站长头像
站长
· 阅读数 18

前言

给一些不知道白金之星的同学做一下介绍,白金之星是荒木飞吕彦笔下作品《JOJO的奇妙冒险》中一位主人公空条承太郎的替身,其能力之一是能暂停时间。在学习JVM的时候,看到了JVM中的STW机制,两者给我一种莫名的相似感,于是便有了以下这篇文章

JVM中的“白金之星”:超详细STW(Stop-The-World)解析

正文

什么是 STW

STW 的全称是 "Stop The World",是指 JVM 在执行垃圾回收( GC )时,会暂停所有正在执行的应用程序线程, 让垃圾回收器能够在一个稳定的环境中执行内存回收工作,以确保内存数据的一致性和完整性。

为什么需要STW

  1. 内存一致性:暂停所有应用线程,确保垃圾回收期间内存状态一致,防止内存修改导致数据错误。
  2. 简化实现:在 STW 期间,JVM可以简化垃圾回收算法的实现,避免处理复杂的并发修改问题。
  3. 准确标记和清理:暂停线程使得JVM能够准确地标记和回收垃圾对象,避免遗漏或错误回收。

STW 的影响

  1. 暂停所有应用程序线程:在 STW 期间,应用程序的所有工作线程都会被暂停,只有 GC 线程在运行。这意味着应用程序会停止处理任何用户请求和其他操作,直到垃圾收集完成。
  2. 影响应用程序性能STW 会导致应用程序暂停一段时间,这段时间可能会影响应用程序的响应时间和性能,特别是在对延迟敏感的应用程序中。

JVM中的“白金之星”:超详细STW(Stop-The-World)解析

常见的垃圾回收算法与STW

Serial GC

  • 特点单线程垃圾回收。
  • STW时间:相对较长,因为整个垃圾回收过程在一个线程中完成。
  • 适用场景:适用于单核CPU或对暂停时间不敏感的应用。

Parallel GC

  • 特点多线程垃圾回收。
  • STW时间比Serial GC短,因为多个GC线程并行工作。
  • 适用场景:适用于多核CPU,要求较高吞吐量的应用。

CMS(Concurrent Mark-Sweep) GC

  • 特点并发标记-清除算法。
  • STW时间:标记阶段和清除阶段与应用线程并发执行,STW时间较短,但存在碎片化问题。
  • 适用场景:适用于对暂停时间敏感的应用,如Web服务器。

G1(Garbage-First) GC

  • 特点:面向大堆内存并发压缩算法。
  • STW时间:设计目标是控制在可预测的短暂停时间内,分区管理内存,逐步回收。
  • 适用场景:适用于大内存应用和需要可预测暂停时间的场景。

STW时间太短或太长会怎么样

STW时间太短的影响

  1. 频繁GC触发:频繁的 GC 触发会导致应用程序整体吞吐量下降,因为 CPU 频繁用于 GC 操作,而不是应用程序逻辑。

  2. 不完全回收:老年代中的垃圾可能不能被及时回收,导致内存利用率不高,可能最终触发 Full GC

  3. 应用抖动:这种抖动会影响应用程序的稳定性和响应时间,尤其是在对延迟敏感的应用中。

STW时间太长的影响

  1. 用户体验差:用户会感觉到明显的卡顿,甚至可能认为应用程序崩溃。尤其是实时交互系统(如游戏、金融交易系统等)影响更大

  2. 超时错误:客户端和其他系统可能会收到超时错误,影响业务流程和用户体验。

  3. 吞吐量下降:整体吞吐量下降,影响系统的性能和处理能力。

如何减少 STW 事件的影响

  1. 调优 JVM 参数:通过调整 JVMGC 参数,可以优化垃圾收集的性能,减少 STW 时间。例如:

    • -XX:MaxGCPauseMillis=<N>:设置最大 GC 暂停时间目标。
    • -XX:GCTimeRatio=<N>:设置 GC 时间与应用程序运行时间的比例。
    • -XX:+UseG1GC:启用 G1 垃圾收集器。
    • -XX:+UseConcMarkSweepGC:启用 CMS 垃圾收集器。
  2. 监控和分析 GC 日志:定期监控和分析 GC 日志,可以了解 STW 事件的频率和持续时间,识别出性能瓶颈并进行针对性的优化, 可以使用如 JVisualVMGCViewer 等工具进行分析。

  3. 分代垃圾收集JVM 使用分代垃圾收集策略,将堆内存分为新生代和老年代,不同代使用不同的垃圾收集算法,新生代的回收速度更快,减少 STW 时间。

实操感受

代码

JVM中的“白金之星”:超详细STW(Stop-The-World)解析 输入以下命令启动

javac STWDemo.java
java -Xlog:gc,safepoint -Xms512m -Xmx512m STWDemo

结果:

JVM中的“白金之星”:超详细STW(Stop-The-World)解析

[0.034s][info][gc] Using G1
开始
[0.169s][info][gc] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 25M->0M(512M) 3.135ms
[0.170s][info][safepoint] Safepoint "G1CollectForAllocation", Time since last: 111977100 ns, Reaching safepoint: 108300 ns, At safepoint: 3609000 ns, Total: 3717300 ns
[0.188s][info][gc       ] GC(1) Pause Young (Normal) (G1 Evacuation Pause) 39M->0M(512M) 1.747ms
[0.188s][info][safepoint] Safepoint "G1CollectForAllocation", Time since last: 16346400 ns, Reaching safepoint: 75600 ns, At safepoint: 2145500 ns, Total: 2221100 ns
结束

逐行分析

  • GC(0) Pause Young (Normal) (G1 Evacuation Pause) 25M->0M(512M) 3.135ms

    • GC(0) :第一次垃圾回收事件。
    • Pause Young (Normal) :年轻代的垃圾回收。
    • G1 Evacuation PauseG1垃圾回收器的Evacuation Pause
    • 25M->0M(512M) :堆内存使用从25MB减少到0MB,堆总大小为512MB。
    • 3.135ms:暂停时间为3.135毫秒。
  • Safepoint "G1CollectForAllocation", Time since last: 111977100 ns, Reaching safepoint: 108300 ns, At safepoint: 3609000 ns, Total: 3717300 ns

    • Safepoint "G1CollectForAllocation" :触发Safepoint的原因:"G1CollectForAllocation"
    • Time since last: 111977100 ns:距离上次Safepoint的时间:111977100纳秒(约111.9771毫秒)。
    • Reaching safepoint: 108300 ns:进入Safepoint所花时间:108300纳秒(约108.3微秒)。
    • At safepoint: 3609000 ns:在Safepoint停留时间:3609000纳秒(约3.609毫秒)。
    • Total: 3717300 ns:总暂停时间(STW):3717300纳秒(约3.7173毫秒)。
  • GC(1) Pause Young (Normal) (G1 Evacuation Pause) 39M->0M(512M) 1.747ms

    • GC(1) :第二次垃圾回收事件。
    • Pause Young (Normal) :年轻代的垃圾回收。
    • G1 Evacuation PauseG1垃圾回收器的Evacuation Pause
    • 39M->0M(512M) :堆内存使用从39MB减少到0MB,堆总大小为512MB。
    • 1.747ms:暂停时间为1.747毫秒。
  • Safepoint "G1CollectForAllocation", Time since last: 16346400 ns, Reaching safepoint: 75600 ns, At safepoint: 2145500 ns, Total: 2221100 ns

    • Safepoint "G1CollectForAllocation" :触发Safepoint的原因:"G1CollectForAllocation"
    • Time since last: 16346400 ns:距离上次Safepoint的时间:16346400纳秒(约16.3464毫秒)。
    • Reaching safepoint: 75600 ns:进入Safepoint所花时间:75600纳秒(约75.6微秒)。
    • At safepoint: 2145500 ns:在Safepoint停留时间:2145500纳秒(约2.1455毫秒)。
    • Total: 2221100 ns:总暂停时间( STW ):2221100纳秒(约2.2211毫秒)。

总结🍊

其实换个思路想想,把 GC 想象成 JVM 里一直有个承太郎隔三岔五在砸瓦鲁多🕛,是不是挺有意思的。

转载自:https://juejin.cn/post/7377357813980512294
评论
请登录