“Java进程咋又突然没了?还没任何报错,都好几天了好奇怪啊。”
上午刚上班不久,旁边的同事就遇到了棘手的技术问题。大概打听下,原来是某个Java应用在执行某个耗时的定时任务的过程中,大概率进程会突然退出,而且应用日志、中间件日志都找不到任何异常。听起来还挺有意思,我默默地登上了出问题的docker容器。
0x01 OOM killer
登上机器后,查看应用和中间件日志,确实没有看到问题。我怀疑是JVM OOM了但没有配置输出,正想加上OOM时的堆栈输出参数,但发现应用启动命令已经包含类似的参数:-XX:+HeapDumpOnOutOfMemoryError -XX:ErrorFile=./hs_err_pid<pid>.log -XX:HeapDumpPath=./java_pid<pid>.hprof。
看来从应用层面查不到什么了,那就再看看系统日志吧。
使用dmesg -T | grep java查看系统日志

果然,从dmesg倒数第二行返回的信息来看,确实是由于oom导致的,但是这里的oom并非JVM的oom,而是Linux系统的oom。
Killed process xxx(java), total-vm:7539096kB, anon-rss:3919048kB file-rss:17312kB, shmem-rss:0kB。
在这台物理内存为4GB的机器上,
`total-vm`是已经分配给java进程的虚拟内存数量(7539096kb=7.02GB)
`anon-rss`是java进程物理内存使用量(3919048kB=3.65GB)
`file-rss`是java进程映射到设备

当Linux系统内存不足时,OOM Killer会选择oom score最高的进程杀死,可能导致Java进程无异常退出。本文分析了Linux OOM与JVM OOM的区别,并提出了解决方案,包括禁止Overcommit、优化代码等。
最低0.47元/天 解锁文章
634

被折叠的 条评论
为什么被折叠?



