java线上问题排查-占用内存的大对象
1️⃣ 查看 Java 进程与内存使用情况
-
使用
top
或ps
找到 Java 进程及其 PID:top # 或者 ps aux | grep java
示例中 Java 进程 PID 为
10397
。
在top
中可以顺便观察 CPU 和内存占用情况。 -
使用
jmap -heap
查看堆内存分布:jmap -heap 10397
- 重点关注:
- 新生代(Young)、老年代(Old) 内存使用比例
- 是否接近堆上限(Xmx)
- 示例判断:如果各区只用了一半,说明 不是堆内存过小 问题。
- 重点关注:
2️⃣ 找出占用内存的大对象
使用 jmap -histo:live
可以查看 JVM 堆中各类对象的数量和内存占用:
jmap -histo:live 10397 | more
- 重点观察占用内存最大的对象:
- 示例:
com.mysql.jdbc.ByteArrayRow
- 示例:
- 分析原因:
- 这类对象通常和数据库查询结果相关
- 可能是查询数据量过大导致堆内存占用异常
- 解决方案:在 SQL 查询中加
LIMIT
限制结果集大小
3️⃣ 排查思路总结
步骤 | 命令 | 作用 |
---|---|---|
查看进程和资源 | top ps aux | grep java | |
查看堆内存分布 | jmap -heap <pid> | 判断堆大小、新生代、老年代是否异常 |
查看对象分布 | jmap -histo:live <pid> | 找出内存占用最大的对象 |
定位问题原因 | 对照对象类型分析 | 例如 JDBC 查询导致大对象,占用堆内存 |
💡 Tips:
-
more
或less
可分页查看对象列表。 -
如果对象数量巨大,可以重定向到文件保存:
jmap -histo:live 10397 > heap_objects.txt
-
排查完成后可结合 MAT(Memory Analyzer Tool) 对
heap dump
文件进行可视化分析,快速找到内存泄漏来源。