真实面经题目 · 原创解析
Full GC 的触发原因和主动触发方式有哪些?
考察 JVM 内存压力和 GC 诊断能力,重点是触发原因、显式 GC 风险、不同收集器差异以及如何从日志定位根因。
真实面经题目 · 原创解析
考察 JVM 内存压力和 GC 诊断能力,重点是触发原因、显式 GC 风险、不同收集器差异以及如何从日志定位根因。
Full GC 通常意味着 JVM 需要对老年代或整个堆做更重的回收。常见触发包括老年代空间不足、年轻代对象晋升失败、元空间不足、大对象或 humongous 对象分配失败、System.gc 或 jcmd/jmap 等显式请求,以及某些收集器并发回收失败后的退化。主动触发可以用 System.gc、jcmd GC.run 或诊断工具,但线上不应把它当治理手段。真正要回答的是看 GC 日志里的触发原因、回收前后容量、暂停时间、晋升速率、老年代增长和引用链,定位是内存泄漏、分配过快、参数不合理还是显式调用。
老年代没有足够连续或可用空间承接晋升对象、大对象分配失败、元空间加载类过多,都可能触发更重的回收。不同收集器名称和细节不同,但本质都是某个关键区域无法继续分配。
年轻代回收后仍存活的对象要晋升到老年代。如果老年代空间不足,或者晋升担保判断风险过高,就可能触发 Full GC 或退化回收。频繁晋升通常和对象生命周期、Survivor 配置、分配速率有关。
System.gc、Runtime.gc、jcmd GC.run、jmap -histo:live 等都可能请求一次完整回收。它们可用于诊断或特定离线场景,但在线上高峰期可能造成长暂停,且不应该替代内存泄漏治理。
CMS 可能出现 concurrent mode failure,G1 可能因为 humongous 对象、to-space exhausted 或并发标记来不及而退化为更重回收。回答时可以说明触发条件要结合具体 GC 算法看日志。
排查频繁 Full GC 要看触发原因、GC 前后各区容量、暂停时间、对象晋升速率、元空间增长、分配热点、堆 dump 引用链和是否有显式 GC 调用。只背触发条件不能指导线上问题。
不一定,取决于 JVM 参数和收集器实现,例如可以通过参数禁用显式 GC 或让它走并发回收。但它通常是危险信号,线上要查调用来源。
先打开并分析 GC 日志,确认触发原因和回收效果;再看老年代是否回收后仍高位、元空间是否增长、对象晋升是否过快;必要时抓堆 dump 分析引用链和对象数量。
说明大量对象仍然可达,可能是缓存无界、集合持有、ThreadLocal 未清理、监听器未注销或类加载器泄漏。也可能是堆目标容量策略导致未立即还给操作系统。
离线诊断、压测验证、停机维护前清理、某些工具采样可以接受;用户请求链路和高峰生产流量中不应依赖主动 GC 释放内存。