题目:Java 进程突然挂了,可能是什么原因?
难度:low
标签:practice/debug, java/process, difficulty/low
评分:⭐⭐⭐☆☆(3/5)
检查java日志,看日志最后是怎么退出的是否有相关记录,如果有异常捕获,oom退出等可以判定是java进程自己退出,如果是显示的日志是优雅退出,证明有外部关闭调用;
如果没有什么日志信息,那么可能是外部强关服务,导致没有记录,检查服务器上命令记录,排查是否存在异常情况;
如果是容器性质服务器,查看服务器日志,看是否有服务器崩溃或者服务器容器重启之类的日志,或者健康告警
优点:抓住了最有效的分界线——有没有留下日志。有日志说明进程走完了自己的关闭流程(可控退出),没日志说明被强杀(不可控退出),再往下才看容器层与宿主机层。这个二分法在真实排障里非常好用。
不足:① 少了最硬的证据 exit code:143=SIGTERM、137=SIGKILL/容器 OOMKilled、134=SIGABRT、1=未捕获异常;② 没提 hs_err_pid*.log 和 core dump——JVM 自身崩溃(SIGSEGV/原生栈溢出)一定会生成这个文件,位置由 -XX:ErrorFile 决定;③ 把「OOM 退出」说得太绝对:默认堆 OOM 只杀死当前线程,进程还活着,只有配了 -XX:+ExitOnOutOfMemoryError 才会退出;④ 没提 dmesg/journal 里的 OOM Killer 记录与 systemd 的 Restart= 策略。
补充:容器场景先看 kubectl describe pod 的 Last State: Terminated / Reason: OOMKilled / Exit Code: 137,这是判断"被容器杀"最快的路径;宿主机场景看 journalctl -u <service> 与 /var/log/messages 里的 Killed process ... (java) total-vm。
核心考点定位:考察能否把"进程没了"拆成三层——JVM 自己退出、被操作系统杀、被编排系统杀,并用 exit code + 落地文件把范围收敛。
知识点拆解:
System.exit()、未捕获异常导致 main 线程结束且无存活非守护线程、Spring Boot 优雅停机(SIGTERM 被注册的 shutdown hook 接住,日志会打印 closing/stop 字样)、-XX:+ExitOnOutOfMemoryError 触发。SIGSEGV 会生成 hs_err_pid<pid>.log(含当前线程栈、JVM 参数、内存映射),并可能生成 core dump。这类"挂"最常见却最容易被误判为被外部杀。dmesg / /var/log/messages;kill -9 留下 137;kill(SIGTERM)留下 143 且一般有优雅关闭日志。RESTARTS 列),超 memory limit 会 OOMKilled;挂了 systemd 的服务若配 Restart=on-failure 会表现为"自己又起来了"。按「底层原理 → 设计权衡 → 工程实践」递进排列。
考察方向:
延伸递进面试题:
OutOfMemoryError 是 Throwable,默认只终止抛出它的线程,进程靠其他非守护线程存活。加 -XX:+ExitOnOutOfMemoryError 让 JVM 在 OOM 后立即退出,配合 -XX:+HeapDumpOnOutOfMemoryError 留证据,再用容器重启自愈。Killed process,无 hs_err;JVM 崩溃一定有 hs_err_pid 或 core,且 exit code 多为 134/139。两者都无则查容器事件与健康检查。【一句话结论】
面试官您好,进程挂了我会先看有没有留下日志和 exit code,用这个二分法区分"自己走的"还是"被杀的"。
【三点展开】
第一,自己退出。看应用日志末行:如果是 Spring 的 closing/stop,说明收到了 SIGTERM 走了优雅停机,那就是发布、缩容或健康检查;如果是未捕获异常或 OOM,要看是不是配了 -XX:+ExitOnOutOfMemoryError——注意默认堆 OOM 只杀线程不杀进程。
第二,被系统杀。exit code 是硬证据:143 是 SIGTERM,137 是 SIGKILL,容器里 137 基本就是 OOMKilled 或被驱逐。再看 kubectl describe pod 的 Last State、宿主机 dmesg 里的 Killed process,以及 systemd 的 Restart 策略。
第三,JVM 自己崩。去找 hs_err_pid*.log,里面有崩溃线程栈和内存映射;有 core dump 更好。这种情况常被误判成被外部杀掉。
【一句边界】
当然,如果是磁盘写满导致日志根本没落盘,上面的日志判断全都失效,所以排查前要先确认磁盘和日志采集链路是正常的。