跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何通过Java代码手动触发Full GC_System.gc()及其副作用

System.gc() 不能保证触发 Full GC,仅是向 JVM 发出建议,实际执行由垃圾收集器和运行时策略决定;启用 -XX:+DisableExplicitGC 可直接忽略该调用。 System.gc() 能不能触发 Full GC? 不能保证。调用
System.gc()
只是向 JVM 发出一个“建议”,是否执行、执行哪种 GC(Minor GC / Full GC / G1 的 Mixed GC 等),完全由当前垃圾收集器和运行时策略决定。JVM 甚至可以在启动参数加
-XX:+DisableExplicitGC
直接忽略它。 哪些场景下 System.gc() 更可能引发 Full GC? 不是靠代码写法,而是靠 JVM 配置和 GC 器行为。比如: 使用 Serial 或 Parallel GC 时,
System.gc()
默认倾向触发 Full GC(但依然可被跳过) 使用 CMS 时,它会尝试触发一次 Concurrent GC,失败后才退化为 Full GC 使用 G1 或 ZGC 时,
System.gc()
通常只触发一次 Young GC,或直接忽略 —— 因为它们设计上不鼓励显式干预 如果堆已严重碎片化 + 老年代占用高,某些 GC 器(如 ParallelOld)在响应
System.gc()
时更可能走 Full GC 路径 为什么线上禁用 System.gc()?常见副作用有哪些? 它破坏 GC 自适应节奏,容易引发雪崩式停顿: 在高负载时强制触发 Full GC,导致 STW 时间陡增(尤其 ParallelOld 下可达秒级) 干扰 G1 的预测模型,让其误判老年代压力,提前进入并发标记阶段 与 RMI、JMX 等内部机制耦合(例如 RMI 默认每小时调一次
System.gc()
),造成不可控的周期性卡顿 在容器环境(如 Kubernetes)中,可能触发 OOM Killer:因为 GC 暂停期间应用无法响应健康检查,被误判为失联 典型错误现象:
java.lang.OutOfMemoryError: Java heap space
出现前,日志里反复看到
Full GC (System.gc())
;或者监控显示 GC 停顿时间出现规律性尖峰。 Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 立即学习 “ Java免费学习笔记(深入) ”; 真要手动触发 Full GC,有什么更可控的办法? 没有“可控”的办法 —— 这本身就是反模式。但若用于测试或诊断,可考虑: 用 JVM TI 工具(如
jcmd VM.runFinalization
或
jstat -gc
配合观察)替代硬编码
System.gc()
测试环境启用
-XX:+PrintGCDetails -XX:+PrintGCDateStamps
,确认
System.gc()
是否真触发了 Full GC(看日志里有没有
Full GC (System.gc())
) 避免在循环、RPC 入口、监听回调等高频路径写
System.gc()
—— 即便只是“试试”,也极易被复制到生产代码里 最常被忽略的一点:很多团队以为加了
if (DEBUG)
就安全,但忘了 classloader 加载后,字节码里仍存在该调用,只要 JVM 参数没禁用,就可能被其他机制意外触发。

相关文章