← 每日面试题 学习看板

Java进程突然挂了,可能是什么原因?

面试题/01实践场景题/问题排查/Java进程突然挂了,可能是什么原因?.md

面试记录 2026-10-22

题目: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 + 落地文件把范围收敛。

知识点拆解:

  1. 进程主动退出:System.exit()、未捕获异常导致 main 线程结束且无存活非守护线程、Spring Boot 优雅停机(SIGTERM 被注册的 shutdown hook 接住,日志会打印 closing/stop 字样)、-XX:+ExitOnOutOfMemoryError 触发。
  2. JVM 崩溃退出:JVM 自身 bug、原生内存越界、栈溢出或 SIGSEGV 会生成 hs_err_pid<pid>.log(含当前线程栈、JVM 参数、内存映射),并可能生成 core dump。这类"挂"最常见却最容易被误判为被外部杀。
  3. 被操作系统杀:内核 OOM Killer 在物理内存耗尽时按 oom_score 选进程,日志落在 dmesg / /var/log/messages;kill -9 留下 137;kill(SIGTERM)留下 143 且一般有优雅关闭日志。
  4. 被编排/健康检查杀:K8s 的 livenessProbe 失败会重启容器(重启次数在 RESTARTS 列),超 memory limit 会 OOMKilled;挂了 systemd 的服务若配 Restart=on-failure 会表现为"自己又起来了"。
  5. 证据优先级:exit code > hs_err > 应用日志末行 > 容器事件 > 内核日志 > Shell history(history 最不可靠,非交互执行不记录)。
按「底层原理 → 设计权衡 → 工程实践」递进排列。

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. 进程退出码 137 和 143 分别代表什么?
  1. 堆 OOM 为什么进程没退出?怎么让它退出?
  1. 怎么区分"被 OOM Killer 杀"和"JVM 自己崩溃"?

第三部分:面试者参考回答(三步法口语化,300-400 字)

【一句话结论】

面试官您好,进程挂了我会先看有没有留下日志和 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 更好。这种情况常被误判成被外部杀掉。

【一句边界】

当然,如果是磁盘写满导致日志根本没落盘,上面的日志判断全都失效,所以排查前要先确认磁盘和日志采集链路是正常的。