OpenJDK进程能否生成core dump,首关是shell资源限制ulimit -c:若输出非unlimited(如为0),则无论JVM参数或core_pattern如何配置,core均不会落地;须同步检查suid_dumpable值是否为2、core_pattern路径是否可写且合法,并用kill -SEGV实测验证。

ulimit -c 输出不是 unlimited 就不算允许
OpenJDK 进程(比如 java)是否能生成 core dump,第一道关卡就是 shell 的资源限制。它不看 Java 参数,只认当前进程启动时继承的 ulimit -c 值。
直接在启动 Java 程序的同一终端里执行:
ulimit -c
如果输出是 0,哪怕你 JVM 加了 -XX:+PrintGCDetails 或改了 /proc/sys/kernel/core_pattern,core 也绝不会落地。
- 临时修复:运行
ulimit -c unlimited后再启动 Java 进程 - 永久生效:往
/etc/security/limits.conf加* soft core unlimited,并确认 PAM 已加载pam_limits.so - 注意:systemd 服务绕过用户 limits,需在
.service文件里显式写LimitCORE=infinity
Java 进程本身可能被内核拒绝写 core
即使 ulimit -c unlimited 成功,OpenJDK 启动的进程仍可能因权限问题被内核静默丢弃 core —— 尤其当它以 root 身份启动但降权为普通用户后(常见于容器或 systemd 服务中)。
检查关键内核开关:
cat /proc/sys/fs/suid_dumpable
必须是 2(不是 0 或 1),否则 setuid/setgid 或 cap_sys_chown 等特权上下文下的 Java 进程会被禁止 dump。
- 临时设为 2:
echo 2 | sudo tee /proc/sys/fs/suid_dumpable - 该值默认常为 0,安全加固系统尤其容易踩这个坑
- 容器环境(如 Docker)需在
docker run时加--cap-add=SYS_PTRACE和--security-opt seccomp=unconfined(若用 seccomp)
core_pattern 配置决定文件去哪、叫什么
OpenJDK 崩溃时,内核按 /proc/sys/kernel/core_pattern 决定 core 是否写入磁盘、路径是否可写、文件名是否含 PID 避免覆盖。
运行:
cat /proc/sys/kernel/core_pattern
如果输出是 |/usr/lib/systemd/systemd-coredump,说明走的是 systemd-coredump 管道机制,core 不落地为文件,而是存进 journal 或 /var/lib/systemd/coredump,需用 coredumpctl 查;如果输出是纯路径(如 /tmp/core.%e.%p),则要确保该路径存在且 Java 进程有写权限。
- 测试路径可写:
sudo -u $(whoami) touch /tmp/core.test 2>/dev/null && echo ok || echo no write perm - 避免用
%h(主机名)或%t(时间戳)导致路径非法,尤其在容器中主机名含斜杠或特殊字符 -
core_uses_pid若为 0,多个 Java 进程崩溃会反复覆盖同一个core文件,建议设为 1:echo 1 | sudo tee /proc/sys/kernel/core_uses_pid
验证 Java 进程是否真能触发 core
别等线上崩了才试。用可控方式主动触发 SIGSEGV:
java -version && pid=$(pgrep -f "java -version"); kill -SEGV $pid 2>/dev/null
然后立刻检查预期位置有没有新 core 文件(如 /tmp/core.java.*)或查 coredumpctl list java。
- 如果没生成,
dmesg -T | tail -20常能看到类似ptrace_may_access denied或Cannot allocate memory(实际是 quota/inode 耗尽,非内存不足) - OpenJDK 自身不拦截 SIGSEGV —— 它依赖内核行为,所以只要上述三步都通,
kill -SEGV就是最准的验证手段 - JVM 参数如
-XX:+UseCoreDumpOnCrash是 OpenJDK 17+ 才有的可选开关,但它是锦上添花,不是前提条件
真正卡住的往往不是 Java 层配置,而是 ulimit、suid_dumpable、core_pattern 这三个内核级开关中某一个没开对,或者目标路径权限/磁盘空间/配额已满。逐项验证比猜更省时间。











