目录
以下使用的是jdk11
jinfo 查看或修改jvm的参数、属性
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204150518668-2108691626.png)
使用示例:
jinfo 23167 # 打印 VM flags and system properties
jinfo -flags 23167 # 打印 VM flags
jinfo -sysprops 23167 # 打印 system properties
jinfo -flag MetaspaceSize 23167 # 打印指定的vm参数值
jinfo -flag [+|-]<name> 23167 # 增加、减少vm参数
jinfo -flag <name>=<value> # 设置vm的值
jstack 查看线程堆栈
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204140149620-234022370.png)
查看线程堆栈:jstack -l -e PID
,-l表示显示锁信息,-e表示显示额外的信息(allocated、defined_classes)
一般将结果输出到一个文件里,分析文件
...
- 第一部分是jvm的信息,堆栈快照的时间、虚拟机版本模式等信息
- 第二部分是jvm内部线程信息(SMR为Safe Memory Reclamation安全内存分配),这里的elements与下面的各个堆栈信息的tid对应,堆栈中的nid与外部操作系统查看到的线程id对应
- 第三部分是线程的具体信息,依次为:
- 线程名称
- 线程id,demon表示是守护线程
- 线程的优先级
- 操作系统中线程的优先级
- cpu,线程获取到的cpu总时间
- elaspsed,线程启动后经过的时间
- allocated,线程分配的字节数
- defined_classes,本线程定义的class个数(要开启 -XX:+PrintExtendedThreadInfo才会输出数据)
- tid,线程id,与SMR中elements中的值对应
- nid,操作系统中线程id,这里显示的都是十六进制的
- 线程的状态,waiting on condition
- 下面就是线程具体的堆栈了
- Locked ownable synchronizers:表示线程可用的用于同步的排它锁对象,Ownable Synchronizer是一个同步器,这个同步器的同步属性是通过使用AbstractOwnableSynchronizer或者它的子类来实现的,如ReentrantLock和ReentrantReadWriteLock中的write-lock
- 第四部分是JVM的线程信息
- 最后一部分是JNI(Java Native Interface)引用的信息,注意这些引用可能会导致内存泄露,因为这些native的引用并不会被自动垃圾回收
排除线程cpu过高
可用通过top -p PID -H
查出线程高的id,转换成16进制,在jstack中根据nid找到该线程的堆栈进行分析可能导致cpu过高的代码
排除死锁
分析jstack里面是否有DeadLock关键字
jmap dump堆到文件
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204140550294-1641997259.png)
一般在oom时将堆提前dump下来,或开启oom dump-XX:+HeapDumpOnOutOfMemoryError
,分析哪些对象占用内存
jmap -dump:live,format=b,file=./t.bin PID
jhsdb
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204141144460-1869962572.png)
有很多子选项,增加对应的选项后可以查看具体命令帮助
查看jvm堆状态
jhsdb jmap --heap --pid PID
jstat 查看gc情况
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204142516271-242657510.png)
基本使用方法为:jstat -选项 -h 5 -t PID 刷新间隔 刷新次数,如jstat -gcutil -t 8048 1s 5
-h 5表示每5行显示一次头部栏,-t表示显示运行的时间戳
jstat -option 可以查看可选的所有选项:
-class 查看类加载统计
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204143123234-1692888189.png)
- 时间戳
- Loaded,加载的class数量
- Bytes,所占空间大小
- Unloaded,未加载数量
- Bytes,未加载所占空间大小
- Time,加载使用的时间
-compiler 查看编译统计
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204143546489-2083593548.png)
- Compiled:编译数量
- Failed:失败数量
- Invalid:不可用数量
- Time:时间
- FailedType:失败类型
- FailedMethod:失败的方法
-gc 查看垃圾回收统计
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204143735679-1296587124.png)
- S0C:第一个幸存区的大小
- S1C:第二个幸存区的大小
- S0U:第一个幸存区的使用大小
- S1U:第二个幸存区的使用大小
- EC:伊甸园区的大小
- EU:伊甸园区的使用大小
- OC:老年代大小
- OU:老年代使用大小
- MC:方法区大小
- MU:方法区使用大小
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- YGC:年轻代垃圾回收次数
- YGCT:年轻代垃圾回收消耗时间
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- GCT:垃圾回收消耗总时间
-gccapacity 查看堆内存统计
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204144034416-1272656472.png)
- NGCMN:新生代最小容量
- NGCMX:新生代最大容量
- NGC:当前新生代容量
- S0C:第一个幸存区大小
- S1C:第二个幸存区的大小
- EC:伊甸园区的大小
- OGCMN:老年代最小容量
- OGCMX:老年代最大容量
- OGC:当前老年代大小
- OC:当前老年代大小
- MCMN:最小元数据容量
- MCMX:最大元数据容量
- MC:当前元数据空间大小
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC:年轻代gc次数
- FGC:老年代GC次数
-gccause 查看gc原因
jstat -gccause -t 8048 1s 5
元空间内存统计,新生代、老年代内存及垃圾回收统计
jstat -gcmetacapacity -t 8048 1s 5
jstat -gcnew -t 8048 1s 5
jstat -gcnewcapacity -t 8048 1s 5
jstat -gcold -t 8048 1s 5
jstat -gcoldcapacity -t 8048 1s 5
-gcutil 垃圾回收总结统计
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204145247760-1735596545.png)
- S0:幸存1区当前使用比例
- S1:幸存2区当前使用比例
- E:伊甸园区使用比例
- O:老年代使用比例
- M:元数据区使用比例
- CCS:压缩使用比例
- YGC:年轻代垃圾回收次数
- YGCT:年轻代垃圾回收时间,从启动到当前时间,单位s
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间,从启动到当前时间,单位s
- CGC:压缩类空间垃圾回收次数
- CGCT:压缩类空间垃圾回收总时间
- GCT:垃圾回收消耗总时间,从启动到当前时间,单位s
-printcompilation 查看jvm编译方法统计
![](/i/l/?n=23&i=blog/1403018/202212/1403018-20221204145419561-221813531.png)
- Compiled:最近编译方法的数量
- Size:最近编译方法的字节码数量
- Type:最近编译方法的编译类型
- Method:方法名标识
jhat web查看工具
jvisualvm可视化工具
总结
- 查看堆栈:
jstack -l -e PID
- 查看堆内存:
jhsdb jmap --heap --pid PID
- dump堆:
jmap -dump:live,format=b,file=./t.bin PID