hs_err_pid.log是jvm native层致命错误(如sigsegv、malloc失败)时生成的临终快照,java层oom或stackoverflow不会触发;需重点分析开头信号类型、pc值、problematic frame及threads节中崩溃线程栈。

直接看 hs_err_pid<pid>.log</pid> 文件,它不是普通应用日志,而是 JVM 自身崩溃时留下的“临终快照”,只在 native 层致命错误(如非法内存访问、malloc 失败)时生成,Java 层的 OOM 或 StackOverflow 不会触发它。
重点看日志开头的崩溃信号和错误帧
文件最上方几行是诊断起点:
- SIGSEGV / SIGBUS / SIGABRT:说明是 native 内存问题。SIGSEGV 常见于空指针解引用或越界访问;SIGBUS 多与内存对齐或 mmap 文件异常有关;SIGABRT 往往是 JVM 主动中止(比如检测到严重不一致)
- pc=0x...、Problematic frame:指出崩溃发生在哪条机器指令、哪个 native 库(如 libjvm.so、libproc.so 或第三方 JNI 库),这是定位根源的关键线索
- “Native memory allocation (malloc) failed”:明确提示原生内存耗尽,和 -Xmx 无关,需检查容器内存限制、JVM 直接内存(-XX:MaxDirectMemorySize)、线程栈总数(-Xss × 线程数)或 native code 泄漏
结合线程状态和调用栈定位上下文
在 “Threads” 小节里重点关注:
- 崩溃线程(通常标为 “Current thread”)的完整 native + Java 调用栈,尤其注意栈顶是否涉及 Unsafe、ByteBuffer、JNI 方法或偏向锁撤销(BulkRevokeBias)等高危操作
- 其他线程是否大量处于
Object.wait()、Unsafe.park()或pthread_cond_wait状态,辅助判断是否存在锁竞争或线程阻塞导致资源积压 - 是否有明显异常线程(如频繁创建/销毁线程、NIO Selector 线程卡死),这些可能间接引发 native 资源枯竭
核对内存与环境配置是否匹配实际资源
别只盯着堆参数,要横向比对:
- 日志中的 “Memory” 小节显示 JVM 已使用的 total memory(含 metaspace、code cache、direct memory、thread stacks),加总后是否接近宿主机或容器的内存上限
- “Command Line” 显示实际生效的 JVM 参数,确认 -Xmx、-XX:MaxDirectMemorySize、-Xss 是否合理,特别注意 Docker 未设内存 limit 时 JVM 可能按宿主机总内存推算 MaxMetaspaceSize
- “OS” 和 “CPU” 小节提供内核版本、glibc 版本、CPU 架构等信息,某些 JVM bug 或 native 库兼容性问题有特定环境依赖
交叉验证系统级日志缩小范围
hs_err 日志只是半边证据,必须联动查看:
-
dmesg -T | grep -i "killed process":确认是否被 Linux OOM Killer 杀掉(输出含 “Out of memory: Kill process …”),此时 hs_err 可能根本没生成,或内容为空 -
cat /var/log/messages | grep -i "java.*sigabrt\|segv":查找内核或 systemd 记录的进程终止事件,与 hs_err 中的 pid/tid 对应 -
ls -l /proc/<pid>/fd | wc -l</pid>:若怀疑文件句柄耗尽,可回溯崩溃前该进程打开的 fd 数量是否逼近 ulimit -n 限制











