Skip to content

jvm 调优

查看 JAR 包的完整路径/主类全名 jps -l 这是回答你问题的最佳命令,能直接显示 JAR 的绝对路径。 查看启动参数和 JVM 参数 jps -lvm 获取最详细的信息,用于深度排查。

jstack - Java 线程堆栈分析工具

功能概述

jstack 用于生成 Java 进程的线程转储(Thread Dump),显示所有线程的堆栈跟踪信息。

基本语法

bash
jstack [options] <pid>

常用选项

bash


# 基本线程转储
jstack 1234

# 显示额外的锁信息(jstack -l)
jstack -l 1234

# 强制生成转储(当进程挂起时)
jstack -F 1234

# 混合模式(Java + Native 堆栈)
jstack -m 1234

# 输出到文件
jstack 1234 > thread_dump.txt

输出解析示例

java
"http-nio-8080-exec-1" #32 daemon prio=5 os_prio=0 tid=0x00007f8a3410e000 nid=0x4a3d waiting on condition [0x00007f8a0f7f7000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x00000000f0a8c4d8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)

关键信息解读 线程名: http-nio-8080-exec-1

线程ID: nid=0x4a3d (十六进制,对应操作系统的线程ID)

状态: WAITING (parking) - 等待状态

堆栈跟踪: 显示代码执行路径

常见线程状态 RUNNABLE: 正在运行或可运行

WAITING: 无限期等待

TIMED_WAITING: 有限期等待

BLOCKED: 等待获取监视器锁

jstat - JVM 统计监控工具

功能概述 jstat 用于监控 JVM 的各种运行时统计信息,特别是垃圾回收相关数据。

基本语法

bash
jstat [generalOption] [outputOptions] <vmid> [interval] [count]

常用命令示例

  1. 类加载统计

    bash
     jstat -class 1234 1000 5

    输出:

    text
        Loaded  Bytes  Unloaded  Bytes     Time
        3257  6234.5      0     0.0       2.35
  2. 垃圾回收统计(最常用)

    bash
    jstat -gcutil 1234 1000 10

    输出:

text
S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
0.00  52.73   8.75  88.95  98.92  96.17    153    4.138     5    1.239    5.378
  1. 详细GC统计
    bash
    jstat -gc 1234 1000 3

    输出字段详解(以 -gcutil 为例)

内存区域使用率 S0: Survivor 0 区使用百分比

S1: Survivor 1 区使用百分比

E: Eden 区使用百分比

O: 老年代使用百分比

M: 元空间使用百分比

CCS: 压缩类空间使用百分比

GC 统计 YGC: Young GC 发生次数

YGCT: Young GC 总耗时(秒)

FGC: Full GC 发生次数

FGCT: Full GC 总耗时(秒)

GCT: 所有 GC 总耗时(秒)

bash

[root@184158 web]$ jstat -gcutil [pid] 1000
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
     -  96.09  87.07  21.88  97.86  90.86     24    0.383     0    0.000    0.383
     -  96.09  87.38  21.88  97.86  90.86     24    0.383     0    0.000    0.383
     -  96.09  87.59  21.88  97.86  90.86     24    0.383     0    0.000    0.383
     -  96.09  87.59  21.88  97.86  90.86     24    0.383     0    0.000    0.383
     -  96.09  87.59  21.88  97.86  90.86     24    0.383     0    0.000    0.383
     -  96.09  87.70  21.88  97.86  90.86     24    0.383     0    0.000    0.383
     -  96.09  87.70  21.88  97.86  90.86     24    0.383     0    0.000    0.383
     -  96.09  88.11  21.88  97.86  90.86     24    0.383     0    0.000    0.383
     -  96.09  88.22  21.88  97.86  90.86     24    0.383     0    0.000    0.383

常用选项组合

bash
# 监控GC情况,每2秒一次,持续监控
jstat -gcutil 1234 2000

# 监控编译情况
jstat -compiler 1234

# 监控JIT编译
jstat -printcompilation 1234 1000

# 完整的GC容量统计
jstat -gccapacity 1234

实际应用场景

  1. 诊断CPU过高
bash
# 1. 找到CPU高的Java进程
top -c

# 2. 获取线程转储
jstack -l 1234 > high_cpu_dump.txt

# 3. 找到对应的native thread ID
printf "%x\n" 45678  # 将十进制线程ID转为十六进制

# 4. 在jstack输出中搜索该nid
  1. 诊断内存泄漏
bash

# 监控GC情况,观察老年代是否持续增长
jstat -gcutil 1234 5000

# 结合jmap生成堆转储
jmap -dump:live,format=b,file=heap.hprof 1234
  1. 诊断应用卡顿
bash
# 检查GC频率和耗时
jstat -gc 1234 1000 10

# 检查线程阻塞情况
jstack 1234 | grep -c "BLOCKED"

检查

bash

 grep -A 10 -B 2 -i "http\|pool\|tomcat\|jetty\|executor\|biz\|business" full_thread_dump.txt

线程转储

bash
jstack -F -l 20844 > full_dump.txt