内存飙高问题怎么排查?
分析:内存飚高如果是发生在java进程上,一般是因为创建了大量对象所导致,持续飚高说明垃圾回收跟不上对象创建的速度,或者内存泄露导致对象无法回收。
1、先观察垃圾回收的情况
- jstat -gc PID 1000 查看GC次数,时间等信息,每隔一秒打印一次。
- jmap -histo PID | head -20 查看堆内存占用空间最大的前20个对象类型,可初步查看是哪个对象占用了内存。
如果每次GC次数频繁,而且每次回收的内存空间也正常,那说明是因为对象创建速度快导致内存一直占用很高;如果每次回收的内存非常少,那么很可能是因为内存泄露导致内存一直无法被回收。
2、导出堆内存文件快照
- jmap -dump:live,format=b,file=/home/myheapdump.hprof PID dump堆内存信息到文件。
如果会挂掉
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/crashes/my-heap-dump.hprof
3、使用visualVM对dump文件进行离线分析,找到占用内存高的对象,再找到创建该对象的业务代码位置,从代码和业务场景中定位具体问题。