JVM 调优工具

JPS

jps -l -v

比较常用的参数:
-q 只显示 pid,不显示 class 名称,jar 文件名和传递给 main 方法的参数

查看所有 java 项目

Jmap

jvm 命令

1
2
3
4
jmap -histo 1996 > ./log.txt    // 查看对象实例、占用空间大小
jmap -heap 1996 // 查看 jvm 堆信息
jmap -dump:format=b,file=eureka.hprof 1996 // 导出堆快照
-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./jvm.dump // 可以设置为内存溢出自动导出,作为快照点

Jvisualvm

JVM 自带工具,启动自动找到所有 jvm 进程

之前导出的 eureka.hprof 文件可放入查看类实例占比

可以自动检测线程死锁

可以远程监控

1
-Djava.rmi.server.hostname=192.168.50.60  // host 主机地址

Jstack

查看线程死锁的堆栈信息

1
jstack 1996| grep -A 10 1cd0 // 1cd0 为十六进制的线程 id,查找此行后 10 行的日志信息

Jinfo

1
2
jinfo -flags 1996 // 查看启动参数
jinfo -sysprops 1996 // 查看 java 系统配置

Jstat

1
2
3
4
5
jstat -gc pid // 查看堆信息
YGC youngGC 次数
YGCT youngGC 总消耗时间
FGC FGCT FullGC 次数 总消耗时间
GCT GC 总时间

年轻代增长速率

1
jstat -gc pid 1000 10 (一秒一次命令,共 10 次) 通过 EU 查看每秒 eden 大概增长多少对象,不同时段的来估算不同情况(高峰期和日常期)

YoungGC 触发频率和每次耗时

1
2
YGCT/YGC 可以得出每次耗时
对象增长速率可以推算大概多少一次 YoungGC

每次 YoungGC 后多少对象存活和进入老年代

1
2
jstat -gc -pid 300000 10 (推算 YoungGC 频率后,假设每 5 分钟一次) 观察 eden 区,survivor 和老年代使用情况,一般 eden 区大量减少,而 s 和 o 都可能增加,
这些增加的对象就是 YoungGC 后存活对象,还可以看出来老年代大概每次进多少对象,从而算出老年代增长速率

FullGC 触发频率和每次耗时

1
 同上

优化思路

尽量每次 YoungGC 存活对象小于 S 的 50%(若超过,会提取最老一批对象进入老年代),都留着年轻代。尽量减少 FullGC 频率

什么情况下 full gc 比 young gc 还多

  1. 元空间不够,导致 full gc
  2. 调用 system.gc(),一般用 -XX:+DisableExplicitGC 参数禁用
  3. 老年代空间分配担保机制