目录
常见的内存溢出
系统里存在无法回收的对象,无法回收的对象越多,占用内存空间就越大,最终导致可用内存大小不足以支持程序运行所需大小。
程序运行时可能会有超大的对象,所占内存大小大于系统分配内存大小。
如何排查内存溢出
1、查看cpu占用最高的进程
#使用top -P命令查看cpu占用最高的进程。
top -P
2、找到进程中占用最高的线程
#查看17038进程中占用cpu最高的线程
top -Hp 17038
将线程号转为16进制,查看这些线程当前正在干什么
#将线程17045转为16进制
printf '%x\n' 17045
#17038为进程号,0x4295为最耗CPU线程的十六进制
jstack 17038 | grep '0x4295' -C10 --color
3、查看当前内存使用情况
最耗CPU的线程都在进行GC,用jmap -heap 17038命令查看当前堆的使用情况(发现老年代现在已占用99.8%+)
4、查看GC的频率
使用jstat -gcutil 17038 5000命令查看GC的频率。O代表老年代占用率,FGC是FullGC次数,FGCT是fullGC时间,可以看出在频繁FullGC但是老年代有资源一直释放不掉
有未释放资源堆积,导致老年代被占满,然后频繁的FullGC但是资源一直释放不了,最终内存溢出。使用jconsole和jvisualvm进行监控
ClassClassPath和ClassClassPathList占用比较大,用到ClassClassPath对象是一个静态的ClassPool,classPath一直被静态的全局pool所持有,导致GC一直释放不掉