文章目录
名称 | 主要作用 |
---|---|
jps | JVM Process Status Tool,心事指定系统内所有的HotSpo虚拟机进程 |
jstat | JVM Statistics Monitoring Tool,用于手机HotSpot虚拟机各方面的运行数据 |
jinfo | Configuration Info for Java,显示虚拟机配置信息 |
jmap | Memory Map For Java,生成虚拟机的内存存储快照(heapdump文件) |
jhat | JVM Heap Dump Browser,用于分析heapdump文件,它会简历一个HTTP/HTML服务器,让用户可以在浏览器上查看分析结果 |
jstack | Stack Trace for Java,显示虚拟机的线程快照 |
jps:虚拟机进程状况工具
作用:列出正在运行的虚拟机进程,并显示虚拟机主类名称以及这些进程的本地虚拟机唯一ID(Local VM Identifier, LVMID)
命令格式:
jps [options] [hostid]
名称 | 主要作用 |
---|---|
jps -q | 只输出LVMID,省略主类的名称 |
jps -m | 输出虚拟机进程启动时传递给朱磊main()函数的参数 |
jps -l | 输出主类的类名,如果进程执行的是jar包,输出jar包路劲 |
jps -v | 输出虚拟机启动时的jvm参数 |
jstat: 虚拟机统计信息监视工具
作用:用于监视虚拟机各种运行状态信息。它可以显示本地或者远程VM进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期间定位虚拟机性能问题的首选工具。
命令格式:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
命令格式中的vmid和LVMID需要特别说明一下:如果是本地虚拟机进程,VMID与LVMID是一致的,如果是远程虚拟机进程,那么VMID的格式应当是:
参数interval和count代表出席间隔和次数,如果忽略这两个参数,说明只查询一次。假设需要没250ms查询一次进程2764垃圾收集状况,以供查询20次,那命令应当是:jstat -gc 2764 250 20
选项options代表着用户希望查询的虚拟机信息,分为:类装载、垃圾收集、运行期编译状况。具体参考下表:
jinfo:java配置信息工具
作用:实时地查看和调整虚拟机各项参数。jinfo的-flag选项可以查询虚拟机启动时未被显式指定的参数。
jinfo -flag MaxNewSize 8356
-XX:MaxNewSize=707264512
jmap:java内存映射工具
jmap用于生成堆转存储快照。还可以查询finalize执行队列、java堆和永久带的详细信息,如空间使用率、当前用的是哪种收集器等。
jmap -dump:file=heap.bin 8356
Dumping heap to C:\Users\mark\heap.bin ... Heap dump file created
jhat:虚拟机堆转储快照分析工具
jhat命令与jmap搭配使用,来分析jmap生成的堆转储快照。jhat内置http服务器,可以在浏览器中查看dump文件的分析结果。但是一般不会再应用服务器上直接使用jhat命令来分析dump文件。原因:
- 分析工作耗时且消耗硬件资源。就算要分析也是复制到其他机器上进行分析。
- jhat的分析功能相对简陋,不如后续要提到的VisualVM等专业分析工具。
C:\Users\mark>jjhat heap.bin
Reading from heap.bin...
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
浏览器访问http://localhost:7000/即可看到下图的分析结果
jstack:Java堆栈跟踪工具
作用:用于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机每一条线程正在执行的方法堆栈的集合,生成线程奎照的主要目的就是定位线程出现长时间挺多的运用,如线程死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间挺多的常见原因。
jstack lvmid
HSDIS:JIT生成代码反汇编
作用:是sun官方推荐的HotSpot虚拟机JIT编译代码的反汇编插件。让HotSpot的-XX:+PrintAssembly指令调用它把动态生成的本地代码还原为汇编代码输出,同时还生成了大量非常有价值的注释,这样就可以通过输出的代码来分析问题。
JDK可视化工具:JConsole
位置:JAVA_HOME\jdk\bin
package com.jian8.basic;
public class SynAddRunable implements Runnable{
int a,b;
SynAddRunable(int a, int b){
this.a = a;
this.b = b;
}
@Override
public void run(){
synchronized (Integer.valueOf(a)){
synchronized (Integer.valueOf(b)){
System.out.println(a+b);
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(new SynAddRunable(1,2)).start();
new Thread(new SynAddRunable(2,1)).start();
}
}
}
一般的,带for循环的版本最多运行2-3次就会遇到线程死锁,程序无法结束。造成死锁的原因是Integer。valueOf()方法基于减少对象创建次数和节省内存的考虑,[-128, 127] 之间的数字会被缓存,当valueOf方法传入参数在这个范围内时,将直接返回缓存中的对象,也就是说,代码中调用了200次valueOf方法一共就返回了两个不同的对象。加入在某个线程的两个synchronized之间发生了一次线程切换,那就会出现线程A等着线程B持有的Integer.valueOf(),线程B又等着线程A持有额Integer.valueOf(2),结果大家都堵塞了。
JDK可视化工具2:VisualVM
VisualVM是目前为止JDK发布的功能最强大的运行监视和故障处理程序。VisualVM的性能分析工具甚至比起JProfiler、YourKit专业且收费的工具不会逊色多少。
下载链接:
https://visualvm.github.io/download.html
使用步骤:
解压下载的程序,进入到bin目录下,打开visualvm.exe即可。