目录
问题报告
一日运维报告某应用JVM进程被OOM kill
[日期] 10-15-108-158 kernel: Out of memory: Kill process 23537 (java) score 846 or sacrifice child [日期] 10-15-108-158 kernel: Killed process 23537, UID 501, (java) total-vm:6458012kB, anon-rss:3364716kB, file-rss:112kB
可以看出进程是在虚拟内存用到6.46G左右,驻留内存用到3.36G左右被OOM kill掉的。
##问题分析
应用概况
该JVM是一个大数据接口程序,供后台报表应用查询一些预计算生成的各种数据,Linux虚拟机配置了6GB内存。应用使用了大量的第三方库连接MySQL,Kylin,Druid和ES等。同时JVM启动参数配置了XX:+HeapDumpOnOutOfMemoryError
选项。
初步分析
Java堆内存,MetaSpace等使用情况
从运维Zabbix系统中可以查出此JVM运行几周的堆内存和GC情况相当正常,并无堆内存泄露的情况。也并无hprof后缀的heap dump生成。
同时Meta Space也无任何泄露迹象。
监控记录显示Java线程数目也正常,并未发生线程数量剧增导致过量使用Thread Stack内存导致的泄露。
Java堆外内存分析
接着怀疑Java应用中是不是有第三方库使用了DirectByteBuffer操作堆外内存导致的泄露。但因为并未监控JVM堆外内存的使用情况,所以需要重新采集。
于是在重启的JVM启动参数中加入-XX:NativeMemoryTracking=detail
,并用crontab每小时运行jcmd {PID} VM.native_memory detail > nmt.$PID.`date '+%Y-%m-%d.%H:%M:%S'`.log
来记录JVM管辖内存的变化。也运行
pmap -x $PID > pmapx.$PID.`