一个应用程序卡死了,查看JVM内存耗尽了,该做些什么呢?
(1)整体资源查看
top命令,查看内存、CPU使用情况是否有明显问题。
(2)查看网络连接数
netstat -an | wc -l
(3)查看内存溢出还是JVM堆内存耗尽
查看OS内存、JVM内存(可通过开启JMX开启JVM监控,用JConsole连接),分析是否存在内存溢出,还是单纯的JVM堆内存耗尽。
(4)查看线程堆栈情况
top -Hp <processID>
查看各个线程中又没有资源使用高的,对于高的,查看16进制的threadID
printf '%x\n' <threadID>
jstack <processID> | grep <16进制的threadID> [-C20] [--color]
其中16进制的threadID为0x开头的线程id,-C20 --color表示显示上下20行,彩色显示threadID
这样就看到了要查找堆栈的堆栈情况。
线程情况可以有BLOCKED ,原因new Connection waiting to lock之类。
可以从堆栈蛛丝马迹分析代码逻辑。
(5)在线查看堆内存使用情况
使用命令 查看堆内存中占用内存最多的前 30 个类实例
jmap -histo <processID>| head -n 30
(6)通过dump文件查看堆内存使用情况
jmap -dump:format=b,file=XXX.dump <pid>
之后使用IBM Heapanalyzer或JProfiler等查看什么对象占了jvm内存。
这个往往是发现问题的关键。
(7)查看GC情况
jstat -gc <pid>查看GC耗时,查看GC日志。
比如看到
[GC (Allocation Failure):这是一次Minor GC.它不区分新生代GC还是老年代GC,括号里的内容是qc发生的原因,这里的AllocationFailure的原因是新生代中没有足够区域能够存放需要分配的数据而失败。
[Full GC (Ergonomics)]:这是一次Full GC.JVM自适应调整导致的GC。
看到一篇和本文相近的,推荐下