Java线上内存泄漏需靠实时监控告警机制,紧盯老年代使用率、Full GC回收率、高频对象增长速率及Metaspace趋势,结合Spring Boot Actuator与Prometheus实现指标采集与精准告警。

Java线上内存泄漏排查不能靠事后救火,得靠一套能“自己盯、自己报、自己留证据”的监控告警机制。核心不是等OOM才动手,而是提前捕捉老年代持续上涨、GC收效变差、对象异常增长这些早期信号。
盯住四个关键内存指标
只看堆内存使用率(比如>90%)太粗糙,容易误报或漏报。真正有区分度的是组合指标:
- 老年代使用率 + Full GC回收率:老年代使用率连续超85%,且Full GC后回落幅度小于10%,说明对象在堆积且难回收
- Full GC频次与回收量:5分钟内发生3次以上Full GC,每次回收对象不足50MB,大概率是内存泄漏正在发生
-
高频对象增长速率:比如
java.util.HashMap$Node、byte[]或你业务中的实体类(如UserDO),每小时实例数增长超10% -
Metaspace使用趋势:尤其在大量使用反射、动态代理、Groovy脚本的场景,
jvm_memory_used_bytes{area="metaspace"}持续上升逼近上限,可能引发OutOfMemoryError: Metaspace
用 Spring Boot + Actuator + Prometheus 快速暴露指标
无需改业务代码,两步就让JVM内存数据可采集:
- 加依赖:
spring-boot-starter-actuator和micrometer-registry-prometheus - 配
application.yml:management: endpoints: web: exposure: include: health,info,metrics,prometheus - 启动后访问
/actuator/prometheus,就能看到jvm_memory_used_bytes{area="heap"}、jvm_gc_collection_seconds_count{gc="G1 Old Generation"}等标准指标
配置可执行的Prometheus告警规则
告警要“能定位、不骚扰”,避免写成“堆内存>80%就告警”。推荐这样定义:
-
中等级别告警(触发自动dump):
(jvm_memory_used_bytes{area="old"} / jvm_memory_max_bytes{area="old"}) > 0.85 and delta(jvm_gc_collection_seconds_count{gc="G1 Old Generation"}[5m]) >= 2 and delta(jvm_memory_used_bytes{area="old"}[5m]) > 10_000_000 - 严重级别告警(触发通知+强制dump):老年代使用率>92% 且过去2分钟Full GC回收量总和
- 所有告警加
for: 2m,防瞬时抖动;通过Alertmanager推送到企业微信或钉钉,并带上服务名、实例IP、当前QPS等上下文
自动抓现场:OOM前就生成并归档堆转储
等OOM再dump,往往进程已挂或dump失败。要在疑似泄漏窗口期主动捕获:
- JVM启动加参数:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dump/oom/(底线保障) - 更进一步:用shell脚本监听GC日志(
-Xloggc:/logs/gc.log),当检测到连续2次Full GC回收率低于15%,立即执行:jmap -dump:live,format=b,file=/dump/auto_$(date +%s).hprof $PID gzip /dump/auto_*.hprof # 上传至MinIO/S3,并记录时间戳、JVM参数、线程数等元数据
- 归档后的
.hprof.gz文件带时间戳和上下文,后续用MAT或脚本分析时,能快速比对不同时间点的对象增长路径
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











