JVM监控及诊断工具(命令行)
环境
jdk11
jps
- jps(Java Process Satus):显示指定系统内所有的HotSpot虚拟机进程(查看虚拟机进程信息),可用于查询正在运行的虚拟机进程。
- 基本语法:jps [options] [hostid]
![]()
- options
3.1 -q: 只显示本地虚拟机唯一id
![]()
3.2 -l:输出应用程序主类的全类名或如果进程执行的是jar包,则输出jar完整路径
![]()
3.3 -m:输出虚拟机进程启动时传递给主类main()的参数
![]()
3.4 -v:输出虚拟机进程启动时的JVM参数
![]()
3.5 以上参数可用综合使用
3.6 如果Java进程关闭了默认开启的UsePerfData参数,及-XX:-UsePerfData,那么jps无法探知该Java进程 - hostid:RMT注册表注册的主机名,如果想要远程监控主机上的java程序,需要安装jstatd
jstat
- jstat(JVM Statistics Monitoring Tool),监视虚拟机各种运行状态信息的命令行工具
- 在没有GuI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题
- 官网地址:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html
- 基本语法:jstat -
public class Demo01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
}
}
5.1 -class:显示ClassLoader的相关信息

5.2 -gc: 显示与GC相关的信息

5.3 -gccapacity:显示内容基本与-gc相同,输出主要关注Java堆各个区域使用到的最大、最小空间

5.4 -gcutil:显示内容基本与-gc相同输出主要关注已使用空间占总空间的百分比

5.5 -gccause:与-gcutil功能一样,会额外输出导致最后一次或当前正在发生的GC产生的原因

5.6 -gcnew:显示新生代GC状况

5.7 -gcnewcapacity:显示内容基本与-gcnew相同,输出主要关注使用到的最大、最小空间

5.8 -gcold:显示老年代GC状况

5.9 -gcoldcapacity:显示内容基本与-gcold相同,输出主要关注使用到的最大、最小空间

5.10 -compiler:显示JIT编译器编译过的方法、耗时等信息

5.11 -printcompilation:输出已经被JIT编译过的方法

6. interval:以指定单位、秒(s) 或毫秒(ms) 表示的采样间隔。默认单位是毫秒。必须是正整数。指定后,该jstat命令会在每个时间间隔生成其输出

7. count:用于指定查询的总次数

8. -t参数:可以在输出信息前加上一个Timestamp列,显示程序的运行时间。单位:秒
我们可以比较Java进程的启动时间以及总GC时间(GCT 列),或者两次测量的间隔时间以及总 GC时间的增量,来得出GC时间占运行时间的比例。如果该比例超过20%,则说明目前堆的压力较大;如果该比例超过90%,则说明堆里几乎没有可用空间,随时都可能抛出OOM异常。|

9. -h参数:可以在周期性数据输出时,输出多少行数据后,输出一个表头信息

jinfo
- 官方文档:https://docs.oracle.com/en/java/javase/11/tools/jinfo.html
- jinfo(Configuration Info for Java): 查看虚拟机配置参数信息。此命令是实验性的,不受支持。对于核心文件,使用jhsdb jinfo
- 语法:jinfo
- options
4.1 默认输出全部的参数和系统属性
![]()
4.2 -flag name:输出对应名称的参数
![]()
4.3 -flag[+-]name:启用或禁用指定的布尔命令行标志,只有被标记为manageable的参数才可以被动态修改
![]()

4.4 -flag name = value:设置name的值

4.5 -flags:输出全部参数

4.6 -sysprops:输出系统属性

4.7:java -XX:+PrintFlagsInitial:查看所有JVM参数启动的初始值

4.8 java -XX:+PrintFlagsFinal:查看所有JVM参数的最终值

4.9 java -XX:+PrintCommandLineFlags:查看被用户或JVM设置过的参数的信息

jmap
- jmap(JVM Memory Map):获取dump文件、目标Java进程的内存相关信息(包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等)
- 官方文档:https://docs.oracle.com/en/java/javase/11/tools/jmap.html
![]()
- options
4.1 -dump:生存dump文件
4.1.1 live— 指定时,仅转储活动对象;如果未指定,则转储堆中的所有对象。
4.1.2 format=b— 转储 Java 堆为hprof二进制格式
4.1.3 file=filename — 将堆转储到 filename
public static void main(String[] args) {
List<String> list = new ArrayList<>();
while (true) {
list.add(new String());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


4.2 -dump:live:只保存堆中的存活对象


4.3 -heap:输出整个堆空间的详细信息

4.4 -histo:输出堆中对象的统计信息,-histo:live只统计堆中存活的对象


4.5 -permstat:以ClassLoader以统计口径输出永久代的内存状态信息,仅Linux、Solaris系统有效
4.6 finalizerinfo:显示在F-Queue中等待Finalizer线程执行finalize方法的对象,仅Linux、Solaris系统有效
4.7 -F:当虚拟机进程对-dump选项没有任何响应时,可使用此选项强制执行生成dump文件,仅Linux、Solaris系统有效
4.8 -h|help:帮助命令
4.9 -j
5 -XX:HeapDumpOnOutOfMemoryError: 当程序发生OOM时,自动导出dump文件;
-XX:HeapDumpPath: 指定堆快照保存的位置;
例如:-Xmx100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\c.hprof
public static void main(String[] args) {
List<String> list = new ArrayList<>();
while (true) {
list.add(new String());
}
}




6. 由jmap导出的堆快照必定是安全点位置的,可能导致基于该堆快照的分析结果存在偏差
7. 如果某个线程长时间无法跑到安全点,jmap将一直等下去
jhat
- 官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jhat.html
- jhat(JVM Heap Analysis Tool):与jmap搭配使用,用于分析jmap生存的heap dump文件,jhat内置了一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,用户可以在浏览器中查看分析结果(分析虚拟机转储快照信息)
- 使用了jhat命令,就启动了一个http服务,端口是7000,即http:/ /localhost:7000/,就可以在浏览器里分析
- jhat命令在JDK9、10中已经被删除,官方建议用VisualVM代替
jstack
- 官方文档:https://docs.oracle.com/en/java/javase/11/tools/jstack.html
- jstack(JVM Stack Tree):用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)。线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。
- 语法:jstack [options] pid
- 在thread dump中,要注意以下几种状态
4.1 死锁,Deadlock(重点关注)
4.2 等待资源,waiting on condition(重点关注)
4.3 等待获取监视器,waiting on monitor entry(重点关注)
4.4 阻塞,Blocked(重点关注)
4.5 执行中,Runnable
4.6 暂停,suspended
4.7 对象等待中,Object wait()或TIMED_WAITING
4.8 停止,parked - jstack管理远程进程:在远程程序的启动参数中添加:
5.1 -Djava.rmi.server.hostname=···..
5.2 -Dcom.sun.management.jmxremote
5.3 -Dcom.sun.management.jmxremote.port=8888
5.4 -Dcom.sun.management.jmxremote.authenticate=false
5.5 -Dcom.sun.management.jmxremote.ssl=false - options参数
6.1 -F:当正常输出的请求不被响应时,强制输出线程堆栈
6.2 -l:除堆栈外,显示关于锁的附加信息
public static void main(String[] args) {
Map<Thread,StackTraceElement[]> maps = Thread.getAllStackTraces();
Set<Map.Entry<Thread,StackTraceElement[]>> entries = maps.entrySet();
for (Map.Entry<Thread,StackTraceElement[]> en : entries) {
Thread key = en.getKey();
StackTraceElement[] value = en.getValue();
System.out.println("Thread name is\t" + key.getName());
for (StackTraceElement s : value) {
System.out.println("\t" + s.toString());
}
}
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
}

6.3 -m:如果调用本地方法的话,可以显示C/C++的堆栈
6.4 -h:帮助
jcmd
- 用来实现除了jstat之外所有命令的功能,例如导出堆、内存使用等
- 官方文档:https://docs.oracle.com/en/java/javase/11/tools/jcmd.html
- 官方推荐用jcmd代替jmap
- 基本语法
4.1 jcmd -l:列出所有的JVM进程
![]()
4.2 jcmd pid help:针对指定的进程,列出支持的所有命令

4.3 jcmd pid 具体命令:显示指定进程的指定命令的数据
jstatd
- 远程主机信息收集,为了启用远程监控,需要配合使用jstatd工具
- 官方文档:https://docs.oracle.com/en/java/javase/11/tools/jstatd.html











浙公网安备 33010602011771号