在 java 垃圾回收中实现停顿优先,核心配置是选用 g1 垃圾收集器并开启低延迟模式。具体做法是在启动参数中添加 -xx:+useg1gc 启用 g1,同时设置 -xx:maxgcpausemillis=200(单位毫秒)来指定目标最大停顿时间。jvm 会根据这个目标值动态调整年轻代大小和混合收集的频率,从而尽量满足停顿时间的要求。

G1 收集器如何根据目标停顿时间调整堆内存分配
G1 收集器通过动态调整年轻代(Young Generation)的大小来控制停顿时间。当设置的 MaxGCPauseMillis 较小时,JVM 会倾向于保持较小的年轻代,以便更快地完成 Young GC;反之,如果允许较长的停顿,JVM 可能会扩大年轻代以提高吞吐量。这种调整是基于历史回收数据进行的预测性管理。

-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xms4g -Xmx4g
预期结果:JVM 启动后,G1 收集器开始运行,并根据初始的堆内存分布进行 Young GC。随着运行时间的推移,G1 会根据实际的回收耗时动态调整 RSet(Remembered Set)的处理策略和 Mixed GC 的触发阈值,以逼近设定的 200ms 停顿目标。
立即学习“Java免费学习笔记(深入)”;
G1 混合收集(Mixed GC)的触发条件与执行流程
除了常规的 Young GC,G1 的核心优势在于 Mixed GC。当老年代(Old Gen)中被回收对象占用的空间比例超过阈值(默认 45%,由 -XX:G1HeapWastePercent 控制)时,G1 会触发 Mixed GC。此时,G1 会选择一部分老年代区域(Humongous 区域除外)与整个年轻代一起进行回收,以释放足够的内存并减少停顿时间。

-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=45
预期结果:当老年代占用率达到 45% 时,G1 启动并发标记周期。标记结束后,若满足回收价值阈值,则触发 Mixed GC。Mixed GC 会暂停应用线程(Stop-The-World),回收选定的老年代区域和所有年轻代区域,然后恢复应用运行。这一过程旨在平衡停顿时间和内存利用率。
当 MaxGCPauseMillis 设置为极小值(如 10ms)时的实际行为
如果将 MaxGCPauseMillis 设置为极小值(例如 10ms),G1 会极力压缩年轻代大小,并可能更频繁地触发 Mixed GC。然而,由于硬件限制和 JVM 内部开销,停顿时间不可能无限降低。过小的目标值可能导致频繁的 Full GC 或 Mixed GC,反而增加系统负载,甚至因无法在规定时间内完成回收而触发紧急 Full GC。
-XX:+UseG1GC -XX:MaxGCPauseMillis=10 -Xms4g -Xmx4g
预期结果:JVM 启动后,年轻代大小被限制在极小范围。应用程序运行时,Young GC 非常频繁但停顿极短。一旦老年代增长较快,G1 会迅速触发 Mixed GC。若 Mixed GC 也无法在 10ms 内完成,JVM 可能会尝试调整策略,但在极端情况下仍可能引发较长的停顿,需监控 GC 日志确认实际效果。


















