JVM 异常崩溃排查全指南:从 Core Dump 到根因定位

JVM 崩溃(Crash)是生产环境中最棘手的故障之一,它可能由多种原因引起:JNI 调用错误、JVM Bug、系统资源耗尽、硬件故障,甚至是 JDK 版本不兼容。本文将系统性地介绍 JVM 崩溃排查的完整方法论,涵盖每一步的操作细节和工具使用。


一、JVM 崩溃的常见类型

常见 JVM 运行时异常类型

  1. 内存溢出 OOM
    Java heap space:堆内存溢出,对象过多、内存泄漏
    Metaspace:元空间溢出,类、方法、动态代理过多
    GC overhead limit exceeded:GC 频繁却回收极少,CPU 飙高
  2. 栈相关异常
    StackOverflowError:递归死循环、方法调用层级过深
    Unable to create new native thread:线程数超限、系统资源耗尽
  3. GC 异常
    Full GC 频繁、GC 卡顿严重、STW 时间过长
    GC 后内存不释放,内存持续走高
  4. 类加载 / 编译异常
    NoClassDefFoundError、ClassNotFoundException
    UnsatisfiedLinkError 本地库加载失败

1.1 崩溃信号分类

信号 含义 典型原因
SIGSEGV (11) 段错误/非法内存访问 JNI 空指针、堆外内存越界、JVM Bug
SIGBUS (7) 总线错误 内存对齐问题、硬件故障、文件映射损坏
SIGILL (4) 非法指令 CPU 指令集不兼容、JVM 版本与架构不匹配
SIGABRT (6) 异常终止 assert 失败、内存分配失败、GC 异常
SIGFPE (8) 浮点异常 除以零、数值溢出(极少见)

1.2 崩溃日志位置

JVM 崩溃时会自动生成 hs_err_pid.log 文件,常见位置:

bash 复制代码
# 默认位置(JVM 工作目录)
./hs_err_pid12345.log

# 通过参数指定位置
-XX:ErrorFile=/var/log/jvm/hs_err_pid%p.log

# 同时生成 Core Dump(Linux)
-XX:+CreateCoredumpOnCrash
ulimit -c unlimited  # 确保系统允许生成 core 文件

二、排查第一步:收集崩溃现场

2.1 确认崩溃日志存在

bash 复制代码
# 查找最近的崩溃日志
find / -name "hs_err_pid*.log" -mtime -1 2>/dev/null

# 查看崩溃时间
ls -la /path/to/hs_err_pid*.log

# 确认 core dump 文件
find / -name "core.*" -mtime -1 2>/dev/null

2.2 收集系统环境信息

bash 复制代码
# 操作系统版本
cat /etc/os-release
uname -a

# JDK 版本(极其重要)
java -version
java -XshowSettings:all -version 2>&1 | head -20

# 系统资源状态
free -h
df -h
ulimit -a

# 当前运行的 JVM 进程
ps -ef | grep java
jps -lvm

2.3 保留现场的关键操作

bash 复制代码
# 1. 立即备份崩溃日志
cp hs_err_pid12345.log /backup/crash-$(date +%Y%m%d-%H%M%S).log

# 2. 备份 core dump(如果存在且文件很大,可压缩)
cp core.12345 /backup/core-$(date +%Y%m%d-%H%M%S)
# 或
gzip -c core.12345 > /backup/core-$(date +%Y%m%d-%H%M%S).gz

# 3. 导出当前 JVM 的启动参数
jcmd <pid> VM.flags 2>/dev/null || cat /proc/<pid>/cmdline | tr '\0' ' '

# 4. 记录系统日志
journalctl --since "1 hour ago" > /backup/system-$(date +%Y%m%d-%H%M%S).log

三、排查第二步:分析 hs_err_pid 日志

3.1 日志结构总览

hs_err_pid 日志包含以下关键段落(按出现顺序):

复制代码
1. 崩溃摘要(Crash Summary)
2. 线程信息(Thread Information)
3. 进程信息(Process Information)
4. 系统信息(System Information)
5. 内存映射(Memory Map)
6. VM 参数(VM Arguments)
7. 环境变量(Environment Variables)
8. 信号处理器(Signal Handlers)

3.2 关键段落详解

段落 1:崩溃摘要(定位问题类型)
text 复制代码
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f8b1c2a3f20, pid=12345, tid=0x00007f8b1b9fe700
#
# JRE version: OpenJDK Runtime Environment (17.0.8+7) (build 17.0.8+7-Ubuntu-1)
# Java VM: OpenJDK 64-Bit Server VM (17.0.8+7, mixed mode, sharing, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# C  [libnative.so+0x3f20]  Java_com_example_NativeBridge_processData+0x120

解读要点

  • SIGSEGV:段错误,非法内存访问
  • pc=0x00007f8b1c2a3f20:程序计数器地址,崩溃发生的指令位置
  • libnative.so+0x3f20 :崩溃发生在 libnative.so 库的 0x3f20 偏移处
  • Java_com_example_NativeBridge_processData:JNI 方法名,说明是 JNI 调用导致
段落 2:线程栈跟踪(定位代码位置)
text 复制代码
---------------  T H R E A D  ---------------

Current thread (0x00007f8b1800b800):  JavaThread "http-worker-3" daemon [_thread_in_native, id=12350, stack(0x00007f8b1b8fe000,0x00007f8b1b9ff000)]

Stack: [0x00007f8b1b8fe000,0x00007f8b1b9ff000],  sp=0x00007f8b1b9fd8a0,  free space=1022k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libnative.so+0x3f20]  Java_com_example_NativeBridge_processData+0x120
C  [libnative.so+0x2a00]  process_buffer+0x80
j  com.example.NativeBridge.processData([B)I+0
j  com.example.DataProcessor.processChunk(Ljava/nio/ByteBuffer;)V+15
j  com.example.HttpWorker.run()V+89
v  ~StubRoutines::call_stub
V  [libjvm.so+0x8a3f20]  JavaCalls::call_helper+0x3a0

关键信息

  • JavaThread "http-worker-3":崩溃线程名称
  • _thread_in_native:线程正在执行 Native 代码(JNI)
  • Native frames:Native 调用栈,从下往上是调用链
  • j com.example.NativeBridge.processData:对应的 Java 方法
段落 3:寄存器状态(底层调试)
text 复制代码
Registers:
RAX=0x0000000000000000, RBX=0x00007f8b1800b9d0, RCX=0x0000000000000064
RDX=0x0000000000000000, RSP=0x00007f8b1b9fd8a0, RBP=0x00007f8b1b9fd8c0
RSI=0x0000000000000000, RDI=0x00007f8b1c2a3f00, R8=0x0000000000000001
R9=0x0000000000000000, R10=0x0000000000000000, R11=0x0000000000000246
R12=0x00007f8b1800b800, R13=0x00007f8b1b9fd950, R14=0x00007f8b1b9fd960
R15=0x00007f8b1800b800, RIP=0x00007f8b1c2a3f20

注意:RAX=0 且是目标地址,说明访问了空指针。

段落 4:内存映射(定位库文件)
text 复制代码
Memory map around native instruction:

[0x00007f8b1c2a3000-0x00007f8b1c2a4000] r-xp 00003000 08:01 1310724  /opt/app/lib/libnative.so

确认崩溃指令所在的内存页权限为 r-xp(可读可执行),说明是代码段。


四、排查第三步:使用专业工具深度分析

4.1 工具一:jcmd(JDK 自带,轻量诊断)

bash 复制代码
# 列出所有 Java 进程
jcmd -l

# 查看指定进程的 VM 信息
jcmd <pid> VM.version
jcmd <pid> VM.flags          # 查看 JVM 参数
jcmd <pid> VM.command_line   # 查看启动命令

# 生成线程 Dump
jcmd <pid> Thread.print > thread_dump.txt

# 生成堆 Dump(崩溃前如果有机会执行)
jcmd <pid> GC.heap_dump /tmp/heap.hprof

# 查看 GC 统计
jcmd <pid> GC.run             # 触发 GC
jcmd <pid> GC.class_histogram # 类实例统计

4.2 工具二:jstack(线程分析)

bash 复制代码
# 打印所有线程栈
jstack -l <pid> > jstack.log

# 检测死锁
jstack -l <pid> | grep -A 50 "Found one Java-level deadlock"

# 打印混合栈(Java + Native)
jstack -m <pid> > jstack_mixed.log

4.3 工具三:jmap(内存分析)

bash 复制代码
# 查看堆概要
jmap -heap <pid>

# 查看堆中对象的统计信息
jmap -histo <pid> | head -30

# 生成堆转储文件(线上慎用,会 STW)
jmap -dump:format=b,file=/tmp/heap.hprof <pid>

# 查看 finalizer 队列(排查 Finalizer 导致的内存泄漏)
jmap -finalizerinfo <pid>

4.4 工具四:jinfo(运行时参数查看与修改)

bash 复制代码
# 查看所有 VM 参数
jinfo -flags <pid>

# 查看特定参数值
jinfo -flag MaxHeapSize <pid>

# 动态修改参数(仅支持部分参数)
jinfo -flag +PrintGCDetails <pid>
jinfo -flag MinHeapFreeRatio=20 <pid>

4.5 工具五:jstat(GC 与内存监控)

bash 复制代码
# 每 1 秒采样一次,共 10 次
jstat -gcutil <pid> 1000 10

# 输出示例:
#   S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
#   0.00   0.00  15.23  45.67  98.12  95.34   1234    45.6     12     8.9    54.5

# 各列含义:
# S0/S1: Survivor 区使用率
# E: Eden 区使用率
# O: 老年代使用率
# M: 元空间使用率
# YGC/YGCT: Young GC 次数/总时间
# FGC/FGCT: Full GC 次数/总时间

# 查看类加载统计
jstat -class <pid> 1000 5

4.6 工具六:jdb(Java 调试器)

bash 复制代码
# 附加到运行中的进程
jdb -attach <pid>

# 常用命令
> threads                    # 列出所有线程
> thread <thread_id>       # 切换到指定线程
> where                      # 打印当前线程栈
> print <expr>               # 打印表达式值
> dump <object_id>           # 打印对象详情
> stop at com.example.MyClass:42   # 设置断点
> cont                       # 继续执行
> exit                       # 退出

4.7 工具七:jhsdb(JDK 9+,服务性代理)

bash 复制代码
# 分析 core dump 文件
jhsdb jstack --core core.12345 --exe /usr/lib/jvm/java-17/bin/java

# 分析堆(从 core dump 中提取)
jhsdb jmap --core core.12345 --exe /usr/lib/jvm/java-17/bin/java

# 交互式分析
jhsdb clhsdb --core core.12345 --exe /usr/lib/jvm/java-17/bin/java

4.8 工具八:GDB(分析 Core Dump)

bash 复制代码
# 加载 core dump
gdb /usr/lib/jvm/java-17/bin/java core.12345

# 常用 GDB 命令
(gdb) bt                    # 打印完整调用栈
(gdb) bt full               # 包含局部变量
(gdb) info registers        # 查看寄存器
(gdb) info threads          # 查看所有线程
(gdb) thread 5              # 切换到线程 5
(gdb) frame 3               # 切换到第 3 帧
(gdb) print *ptr            # 打印指针内容
(gdb) x/16x $rsp            # 查看栈内存
(gdb) disassemble           # 反汇编当前函数
(gdb) info sharedlibrary    # 查看加载的共享库

# 查找 JNI 调用
(gdb) info symbol 0x00007f8b1c2a3f20
(gdb) info line *0x00007f8b1c2a3f20

4.9 工具九:MAT(Memory Analyzer Tool)- 堆分析

bash 复制代码
# 1. 下载 MAT:https://eclipse.dev/mat/
# 2. 打开堆转储文件
# 3. 运行 "Leak Suspects Report" 自动分析内存泄漏
# 4. 查看 "Dominator Tree" 找到大对象持有者
# 5. 查看 "Path to GC Roots" 找到引用链

4.10 工具十:Arthas(线上诊断神器)

bash 复制代码
# 安装
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

# 常用命令
dashboard                   # 实时系统面板
thread                      # 线程信息
thread -n 10                # CPU 占用前 10 的线程
thread <tid>                # 查看指定线程栈
jvm                         # JVM 信息
heapdump /tmp/dump.hprof    # 生成堆转储
trace com.example.Service processData '#cost>100'  # 方法耗时追踪
watch com.example.Service processData '{params,returnObj,throwExp}'  # 方法入参出参监控
stack com.example.Service processData  # 方法调用栈
tt -t com.example.Service processData  # 方法执行时空隧道

五、排查第四步:常见崩溃场景与根因定位

5.1 场景一:JNI 调用导致的 SIGSEGV

日志特征

text 复制代码
# Problematic frame:
# C  [libnative.so+0x3f20]  Java_com_example_NativeBridge_processData+0x120

排查步骤

bash 复制代码
# 1. 确认 JNI 库文件
ldd /opt/app/lib/libnative.so

# 2. 检查库文件是否损坏
md5sum /opt/app/lib/libnative.so
file /opt/app/lib/libnative.so

# 3. 使用 nm/objdump 查看符号表
nm -D /opt/app/lib/libnative.so | grep processData
objdump -d /opt/app/lib/libnative.so | grep -A 20 "<Java_com_example_NativeBridge_processData>"

# 4. 检查 JNI 参数传递
# 在 Java 代码中添加 null 检查
# 确认数组越界保护

解决方案

  • 在 JNI 代码中添加空指针检查
  • 使用 GetArrayLength 验证数组边界
  • 确保 Native 内存分配成功后再使用

5.2 场景二:元空间溢出导致的崩溃

日志特征

text 复制代码
# java.lang.OutOfMemoryError: Metaspace
# Internal exceptions (10 events):
# Event: 0.123 Thread 0x00007f8b1800b800 Exception <a 'java/lang/OutOfMemoryError'{0x00000000c0000000}: Metaspace> (0x00000000c0000000)

排查步骤

bash 复制代码
# 1. 查看类加载情况
jcmd <pid> VM.classloader_stats

# 2. 查看类加载器层次
jcmd <pid> VM.class_hierarchy

# 3. 使用 jstat 监控元空间
jstat -class <pid> 1000 10

# 4. 分析类加载日志(需开启 -XX:+TraceClassLoading)

解决方案

bash 复制代码
# 增大元空间
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m

# 检查动态代理/字节码生成(如 CGLIB、Javassist)
# 检查 OSGi/热部署导致的类加载器泄漏

5.3 场景三:GC 导致的崩溃(GC Locker)

日志特征

text 复制代码
# A fatal error has been detected by the Java Runtime Environment:
# Internal Error (gcLocker.cpp:XXX), pid=12345, tid=XXX
# guarantee(_jni_lock_count >= count) failed: _jni_lock_count (0) < count (1)

排查步骤

bash 复制代码
# 1. 查看 GC 日志
cat /var/log/gc.log | grep -i "gc locker\|jni\|critical"

# 2. 检查 JNI Critical 区域使用
# 搜索代码中的 GetPrimitiveArrayCritical / ReleasePrimitiveArrayCritical

# 3. 使用 jstack 查看线程状态
jstack <pid> | grep -A 5 "JNI"

解决方案

  • 缩短 JNI Critical 区域持有时间
  • 避免在 Critical 区域执行耗时操作
  • 升级到修复了该问题的 JDK 版本

5.4 场景四:堆外内存(Direct Memory)溢出

日志特征

text 复制代码
# java.lang.OutOfMemoryError: Direct buffer memory
# 或 Native memory allocation (mmap) failed to allocate X bytes

排查步骤

bash 复制代码
# 1. 查看直接内存使用
jcmd <pid> VM.native_memory summary

# 2. 详细查看各区域
jcmd <pid> VM.native_memory detail

# 3. 开启 NMT(Native Memory Tracking)
-XX:NativeMemoryTracking=summary  # 或 detail
# 然后使用:
jcmd <pid> VM.native_memory baseline   # 建立基线
jcmd <pid> VM.native_memory summary.diff  # 查看差异

# 4. 查看堆外内存分配
jcmd <pid> VM.native_memory detail | grep -A 5 "Internal"

解决方案

bash 复制代码
# 限制直接内存大小
-XX:MaxDirectMemorySize=1g

# 检查 Netty/Netty 等框架的 ByteBuf 泄漏
# 使用引用计数确保释放

5.5 场景五:JVM Bug / JDK 版本问题

日志特征

text 复制代码
# Internal Error (os_linux.cpp:XXX), pid=12345, tid=XXX
# Error: guarantee(requested_size <= size) failed

排查步骤

bash 复制代码
# 1. 确认 JDK 版本
java -version

# 2. 检查已知 Bug
# 访问 https://bugs.openjdk.org/
# 搜索错误信息中的文件名和行号

# 3. 检查 JDK 发行版
# Oracle JDK vs OpenJDK vs 各发行版(Adoptium、Amazon Corretto、Azul Zulu)

# 4. 检查操作系统兼容性
uname -a
cat /etc/os-release

解决方案

  • 升级到最新的补丁版本(如 17.0.8 → 17.0.12)
  • 考虑更换 JDK 发行版
  • 如果是已知 Bug,应用临时 workaround

5.6 场景六:系统资源耗尽

排查步骤

bash 复制代码
# 1. 文件描述符
lsof -p <pid> | wc -l
ulimit -n
cat /proc/<pid>/limits | grep "Max open files"

# 2. 内存
free -h
cat /proc/<pid>/status | grep -E "VmRSS|VmSize|VmPeak"
cat /proc/meminfo | grep -E "MemTotal|MemFree|Buffers|Cached"

# 3. 线程数
ps -eLf | grep <pid> | wc -l
ulimit -u
cat /proc/<pid>/status | grep Threads

# 4. 磁盘空间
df -h

六、排查第五步:建立预防机制

6.1 JVM 启动参数加固

bash 复制代码
# ========== 崩溃现场保留 ==========
-XX:+CreateCoredumpOnCrash          # 生成 core dump
-XX:ErrorFile=/var/log/jvm/hs_err_pid%p.log  # 崩溃日志路径
-XX:HeapDumpPath=/var/log/jvm/      # OOM 堆转储路径
-XX:+HeapDumpOnOutOfMemoryError     # OOM 时自动 dump

# ========== 内存监控 ==========
-XX:NativeMemoryTracking=summary     # 开启 NMT
-XX:+PrintGCDetails                  # 打印 GC 详情
-XX:+PrintGCDateStamps              # GC 时间戳
-Xlog:gc*:file=/var/log/jvm/gc.log:time,uptime,level,tags:filecount=10,filesize=100M  # JDK 9+

# ========== 安全加固 ==========
-XX:+DisableExplicitGC               # 禁止 System.gc()
-XX:+UseStringDeduplication          # JDK 8u20+ 字符串去重
-XX:+OptimizeStringConcat             # 字符串拼接优化

6.2 监控告警脚本

bash 复制代码
#!/bin/bash
# jvm_crash_monitor.sh - 定时检查崩溃日志

LOG_DIR="/var/log/jvm"
ALERT_WEBHOOK="https://hooks.slack.com/services/XXX"

# 检查新崩溃
for log in $(find $LOG_DIR -name "hs_err_pid*.log" -mmin -5); do
    PID=$(echo $log | grep -oP 'hs_err_pid\K\d+')
    SIGNAL=$(grep -oP 'SIG\w+' $log | head -1)
    THREAD=$(grep -oP 'Current thread.*' $log | head -1)
    
    # 发送告警
    curl -X POST $ALERT_WEBHOOK \
        -H 'Content-Type: application/json' \
        -d "{
            \"text\": \"🚨 JVM Crash Detected\",
            \"attachments\": [{
                \"color\": \"danger\",
                \"fields\": [
                    {\"title\": \"PID\", \"value\": \"$PID\", \"short\": true},
                    {\"title\": \"Signal\", \"value\": \"$SIGNAL\", \"short\": true},
                    {\"title\": \"Thread\", \"value\": \"$THREAD\", \"short\": false},
                    {\"title\": \"Log\", \"value\": \"$log\", \"short\": false}
                ]
            }]
        }"
    
    # 自动收集现场
    /opt/scripts/collect_crash_info.sh $PID $log
done

6.3 崩溃信息收集脚本

bash 复制代码
#!/bin/bash
# collect_crash_info.sh

PID=$1
LOG_FILE=$2
OUTPUT_DIR="/backup/crash/$(date +%Y%m%d-%H%M%S)-$PID"
mkdir -p $OUTPUT_DIR

# 复制崩溃日志
cp $LOG_FILE $OUTPUT_DIR/

# 收集系统信息
uname -a > $OUTPUT_DIR/system_info.txt
cat /proc/cpuinfo > $OUTPUT_DIR/cpuinfo.txt
free -h > $OUTPUT_DIR/memory.txt
df -h > $OUTPUT_DIR/disk.txt
cat /proc/$PID/status > $OUTPUT_DIR/process_status.txt 2>/dev/null
cat /proc/$PID/limits > $OUTPUT_DIR/process_limits.txt 2>/dev/null
cat /proc/$PID/maps > $OUTPUT_DIR/memory_map.txt 2>/dev/null

# 收集 JVM 信息
jcmd $PID VM.version > $OUTPUT_DIR/jvm_version.txt 2>/dev/null
jcmd $PID VM.flags > $OUTPUT_DIR/jvm_flags.txt 2>/dev/null
jcmd $PID VM.command_line > $OUTPUT_DIR/jvm_cmdline.txt 2>/dev/null

# 收集线程和堆信息(如果进程还在)
jstack -l $PID > $OUTPUT_DIR/thread_dump.txt 2>/dev/null
jmap -heap $PID > $OUTPUT_DIR/heap_info.txt 2>/dev/null

# 打包
tar czf $OUTPUT_DIR.tar.gz $OUTPUT_DIR
echo "Crash info collected: $OUTPUT_DIR.tar.gz"

七、完整排查流程图

复制代码
┌─────────────────────────────────────────────────────────────┐
│                    JVM 崩溃发生                              │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 1: 收集现场                                            │
│  ├── 查找 hs_err_pid*.log                                   │
│  ├── 检查 core dump 文件                                    │
│  ├── 记录系统状态(free, df, ulimit)                        │
│  └── 备份所有相关文件                                       │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 2: 分析崩溃日志                                        │
│  ├── 查看崩溃信号(SIGSEGV/SIGBUS/SIGILL)                   │
│  ├── 定位 Problematic frame                                 │
│  ├── 分析线程栈(Java + Native)                             │
│  └── 检查寄存器和内存映射                                    │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 3: 确定崩溃类型                                        │
│  ├── JNI 调用错误? → 检查 Native 代码                      │
│  ├── 内存溢出? → 分析堆/元空间/直接内存                     │
│  ├── GC 异常? → 检查 GC 日志和参数                          │
│  ├── JVM Bug? → 查询 OpenJDK Bug 库                         │
│  └── 系统资源? → 检查 fd/内存/线程/磁盘                     │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 4: 深度分析(使用工具)                                 │
│  ├── jcmd / jstack / jmap → 运行时信息                     │
│  ├── jhsdb → 分析 core dump                                │
│  ├── GDB → 底层调试                                         │
│  ├── MAT → 堆内存分析                                       │
│  └── Arthas → 线上诊断                                      │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 5: 根因定位与修复                                      │
│  ├── 修复代码(JNI 空指针、内存泄漏)                        │
│  ├── 调整 JVM 参数(堆大小、GC 策略)                        │
│  ├── 升级 JDK 版本                                          │
│  └── 扩容系统资源                                           │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 6: 建立预防机制                                        │
│  ├── 完善 JVM 启动参数                                      │
│  ├── 部署监控告警脚本                                       │
│  ├── 定期健康检查                                           │
│  └── 压测验证修复效果                                       │
└─────────────────────────────────────────────────────────────┘

八、总结

JVM 崩溃排查的核心在于快速收集现场、精准定位根因、系统性修复预防。记住以下要点:

  1. 崩溃日志是黄金hs_err_pid 日志包含了 90% 的诊断信息
  2. core dump 是保险 :开启 -XX:+CreateCoredumpOnCrash,配合 GDB/jhsdb 深度分析
  3. 工具链要熟练:jcmd/jstack/jmap 用于运行时,MAT 用于堆分析,Arthas 用于线上诊断
  4. 预防胜于治疗:完善的参数配置 + 监控告警 + 定期演练,才能将崩溃风险降到最低
相关推荐
2301_782040454 小时前
CSS Flex布局中如何实现导航栏与Logo的左右分布_利用justify-content- space-between
jvm·数据库·python
沐浴露z7 小时前
面试官:静态变量与非静态成员变量的区别?别再死记硬背了!
java·jvm
Chase_______11 小时前
Java 基础语言 ① —— Java 运行机制与开发环境:从 javac 到 JVM 全流程解析
java·jvm·python
xqqxqxxq11 小时前
多线程、进程与JVM 技术笔记
jvm·笔记
cui_ruicheng11 小时前
Linux线程(二):pthread 线程库与线程控制
java·开发语言·jvm
不知名的老吴12 小时前
C++20的jthread使用基础及实例分析
jvm
Devin~Y12 小时前
大厂Java面试实战:Spring Boot/Cloud、Redis/Kafka、JVM调优与Spring AI RAG(内容社区UGC+AIGC客服场景)
java·jvm·spring boot·redis·spring cloud·kafka·mybatis
AI人工智能+电脑小能手12 小时前
【大白话说Java面试题 第42题】【JVM篇】第2题:JVM内存模型有哪些组成部分?
java·开发语言·jvm·面试
青柠代码录12 小时前
【JVM】面试题-对象的内存布局
jvm