踩坑记录:一次生产环境 OOM 排查全流程复盘

一、那个半夜的报警

某日生产环境突然大面积超时,监控显示 JVM 堆内存 100%,Full GC 每秒一次,服务几乎停滞。本文复盘完整排查链路。

二、第一步:确认是不是 OOM

# 看进程内存
top -p $(pgrep -f app.jar)
# 看 GC 频率
jstat -gcutil $(pgrep -f app.jar) 1000

EU/OU 接近 100% 且 FGCT 持续增长,基本锁定堆内存问题。

三、第二步:抓堆转储

# 自动在 OOM 时 dump(推荐提前加)
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprof
# 或手动抓
jmap -dump:live,format=b,file=/tmp/heap.hprof $(pgrep -f app.jar)

四、第三步:用 MAT 分析

打开 Eclipse MAT,看 Dominator Tree,谁占的内存最多一目了然。本次发现 ConcurrentHashMap 里塞了几百万条缓存对象,且从不过期。

五、根因:缓存没设上限

代码里用普通 HashMap 做本地缓存,key 随时间无限增长。修复:

// 改用 Caffeine,带容量和过期
Cache<String, Data> cache = Caffeine.newBuilder()
    .maximumSize(10_000)
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .build();

六、复盘清单

  • 本地缓存必须设容量上限和过期策略。
  • 容器内存限制要合理,避免被 OS OOM Killer 误杀。
  • 提前开 HeapDumpOnOutOfMemoryError,出事能秒定位。
  • 加监控:堆使用率超 80% 就告警,别等故障。

结语

每次 OOM 都是一次免费的教学。把排查过程记下来,下次同类问题十分钟解决。

上一篇 Spring Boot 3.x 新特性与升级实操(Java 17 基线)
下一篇 2026 前端框架对比:React vs Vue vs Svelte 怎么选
最新评论
Docker 网络模式详解:bridge/host 生产选型 - FSData
Docker 网络模式详解:bridge/host 生产选型 - FSData
8月20日
[…] 注意最后那条:把端口绑定到 127.0.0.1,再由宿主机上的 Nginx 反代进来,比直接 -p 80:80 暴露安全得多,也方便统一做
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
8月20日
[…] Pinia 的工程化用法,可以参考我们之前的实战文章 《Vue3 组合式 API + Pinia:状态管理从入门到实战》,那里覆盖了 Sto
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
8月19日
[…] 状态,点一下就能起停容器,配合我们讲过的 Docker Compose 编排 […]
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
8月19日
[…] 缓存三大坑的本质都是”缓存失效导致请求穿透到数据库”。记住口诀:穿透用布隆、击穿用锁、雪崩用错峰。配合合理的过期策略
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
8月19日
[…] Docker 镜像部署。结合我们之前写的 Docker Compose 一键编排实战,可以在 CI […]