[{"data":1,"prerenderedAt":202},["ShallowReactive",2],{"blog-java-full-gc-analyze":3},{"id":4,"title":5,"body":6,"category":187,"date":188,"description":189,"extension":190,"meta":191,"navigation":192,"path":193,"seo":194,"stem":195,"tags":196,"__hash__":201},"blog\u002Fblog\u002Fjava-full-gc-analyze.md","线上 Full GC 故障排查实战：从告警到根因的系统性方法论",{"type":7,"value":8,"toc":174},"minimark",[9,13,22,25,30,36,39,73,77,80,85,88,110,114,117,130,134,137,142,146,149,152,158,161,167],[10,11,5],"h1",{"id":12},"线上-full-gc-故障排查实战从告警到根因的系统性方法论",[14,15,16,17,21],"p",{},"在生产环境中，Full GC 告警往往意味着业务响应出现了不可容忍的停顿（STW）。面对突发的频繁 Full GC，很多时候直觉反应是“赶紧调整 JVM 参数”或者“重启机器”。但实际上，JVM 参数调优只能锦上添花，",[18,19,20],"strong",{},"90% 的频繁 Full GC 问题，根源都出在不合理的代码逻辑或数据结构上","。",[14,23,24],{},"面对 Full GC 故障，我们需要一套克制且系统的方法论。",[26,27,29],"h2",{"id":28},"_1-案发现场别急着重启先保留证据","1. 案发现场：别急着重启，先保留证据",[14,31,32,33,21],{},"系统一旦重启，内存状态烟消云散，故障可能在几天后再次幽灵般重现。在处理任何 JVM 内存问题时，第一原则是：",[18,34,35],{},"先摘除流量，然后立刻保留现场",[14,37,38],{},"必备的三板斧：",[40,41,42,54,67],"ul",{},[43,44,45,48,49,53],"li",{},[18,46,47],{},"Dump 内存快照："," ",[50,51,52],"code",{},"jmap -dump:format=b,file=heap.hprof \u003Cpid>","。这是分析内存泄漏的最核心文件。如果堆内存巨大（如几十GB），注意 Dump 操作本身也会引发长时间的停顿。",[43,55,56,48,59,62,63,66],{},[18,57,58],{},"导出线程栈：",[50,60,61],{},"jstack \u003Cpid> > thread.log","。结合 ",[50,64,65],{},"top -H -p \u003Cpid>","，找出当前消耗 CPU 最多的线程，看看它们到底在干什么。",[43,68,69,72],{},[18,70,71],{},"分析 GC 日志："," 查看发生 Full GC 时的老年代、年轻代、元空间的内存变化。重点关注：Full GC 后，老年代的内存有没有降下来？",[26,74,76],{"id":75},"_2-抽丝剥茧导致-full-gc-的三大元凶","2. 抽丝剥茧：导致 Full GC 的三大元凶",[14,78,79],{},"拿到现场数据后，我们需要带着假设去验证。导致 Full GC 的原因无外乎以下三种典型场景：",[81,82,84],"h3",{"id":83},"场景一内存泄漏full-gc-后老年代依然居高不下","场景一：内存泄漏（Full GC 后老年代依然居高不下）",[14,86,87],{},"这是最棘手的情况。每次 Full GC 只能回收一点点内存，老年代的水位线像阶梯一样不断上涨，最终导致 OOM。",[14,89,90,93,94,97,98,101,102,105,106,109],{},[18,91,92],{},"排查思路："," 将 ",[50,95,96],{},"heap.hprof"," 导入到 MAT（Memory Analyzer Tool）或 JProfiler 中，使用大对象视图（Dominator Tree）查看是谁占用了最多的内存。通常会发现是某些静态 ",[50,99,100],{},"HashMap"," 缓存忘记清理、或者 ",[50,103,104],{},"ThreadLocal"," 使用不当未能及时 ",[50,107,108],{},"remove()"," 导致的生命周期错乱。",[81,111,113],{"id":112},"场景二大对象频发内存分配速率过快","场景二：大对象频发（内存分配速率过快）",[14,115,116],{},"年轻代配置合理，但依然频繁触发 Full GC。这往往是因为业务逻辑中产生了大量的“巨大对象”，导致它们无法放入 Eden 区，直接绕过年轻代晋升到了老年代（如 G1 中的 Humongous Object）。",[14,118,119,121,122,125,126,129],{},[18,120,92],{}," 常见于不良的数据库查询（例如 ",[50,123,124],{},"select *"," 查出了几十万条数据放到 List 里）、大文件的读取、或者是分页接口被恶意传入了 ",[50,127,128],{},"pageSize=100000","。这类问题通过分析线程栈或排查慢 SQL 通常能迅速定位。",[81,131,133],{"id":132},"场景三元空间metaspace撑爆","场景三：元空间（Metaspace）撑爆",[14,135,136],{},"在 JDK 8 之后，方法区移到了堆外的 Metaspace。如果频繁发生 Full GC，且 GC 日志显示老年代空间很充足，那极大概率是元空间扩容触发的。",[14,138,139,141],{},[18,140,92],{}," 通常与动态生成类的技术有关。例如滥用 CGLib、反射，或者在代码中频繁编译运行时的动态脚本当作新类加载。检查是否每次请求都在无限制地生成新的代理类。",[26,143,145],{"id":144},"_3-真实案例复盘被忽略的流式查询","3. 真实案例复盘：被忽略的流式查询",[14,147,148],{},"曾在线上遇到过一次 Full GC，一个系统平时很正常，国庆回来不到一周突然 Full GC告警。",[14,150,151],{},"公司的工具平台有 jmap 之类的能力并且把结果用火焰图呈现，查到了异常占用内存的对象，某个配置模块用 HashMap 做本地缓存，对于一条配置信息有版本控制的需求，新老版本都缓存在 HashMap 中，平时迭代多，经常重启，国庆之前封版，节后也没着急上线，导致 HashMap 中有特别多的配置信息。",[14,153,154,157],{},[18,155,156],{},"恢复和修复：","\n集群重启，代码升级，引入 Caffeine 替换 HashMap 做本地缓存。",[26,159,160],{"id":160},"总结",[14,162,163,164],{},"解决线上 Full GC 问题，犹如医生看病。GC 日志和监控图表是心电图，只能告诉你病状；Heap Dump 是 X 光，能帮你找到病灶所在。而最终的药方，往往隐藏在业务代码最基础的循环和数据加载逻辑中。记住：",[18,165,166],{},"代码质量是因，GC 只是果。",[14,168,169],{},[170,171,173],"a",{"href":172},"\u002Fblog\u002F","返回博客列表",{"title":175,"searchDepth":176,"depth":176,"links":177},"",2,[178,179,185,186],{"id":28,"depth":176,"text":29},{"id":75,"depth":176,"text":76,"children":180},[181,183,184],{"id":83,"depth":182,"text":84},3,{"id":112,"depth":182,"text":113},{"id":132,"depth":182,"text":133},{"id":144,"depth":176,"text":145},{"id":160,"depth":176,"text":160},"JVM调优","2026-03-15","在生产环境中，Full GC 告警往往意味着业务响应出现了不可容忍的停顿（STW）。面对突发的频繁 Full GC，很多时候直觉反应是“赶紧调整 JVM 参数”或者“重启机器”。但实际上，JVM 参数调优只能锦上添花，90% 的频繁 Full GC 问题，根源都出在不合理的代码逻辑或数据结构上。","md",{},true,"\u002Fblog\u002Fjava-full-gc-analyze",{"title":5,"description":189},"blog\u002Fjava-full-gc-analyze",[197,198,199,200],"JVM","Full GC","线上排查","性能优化","chyJn53FglYQiWxXQk3PRv20LmyXid0syDc5Rrl8zjU",1779959653040]