虚拟机调试工具
- 一、命令行工具
- 1.jps
- ①jps -q 只显示进程号
- ②jps -m
- ③ jps -l
- ④jps -v
- 2.Jstat
- jstat 用法
- 示例一:-class
- 示例二: -compiler
- 示例三: -gc
- 示例四: -gccapacity
- 示例五:-gcmetacapacity
- 示例六: -gcnew
- 示例七: -gcnewcapacity
- 示例八: -gcold
- 示例九:-gcoldcapacity
- 示例十: - gcutil
- 示例十一:-gccause
- 示例十二: -printcompilation
- 3.Jinfo
- jinfo 用法
- 参数说明
- option
- Javacore 概述
- 示例一: no option
- 示例二: -flag name
- 示例三:-flag [+|-]name
- 示例四:-flag name=value
- 示例五: -flags
- 示例六:-sysprops
- 4.jmap
- 概述
- jmap 用法
- 参数:
- 示例一:no option
- 示例二:heap
- 示例三:histo[:live]
- 示例四:clstats
- 示例五:finalizerinfo
- 示例六:dump:
- 5.jhat
- 案例:
- 6.jstack
- 方式1:直接查看堆栈信息
- 方式2:
- 二、可视化工具
- 1.jconsole
- ①内存监控
- ②线程监控
- ③线程死锁监控
- 2.visualVM
- ①安装:
- ②插件下载
一、命令行工具
1.jps
官网地址:
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html
JVM Process Status Tool,显示虚拟机进程。
用法:jps [-q] [-mlvV]
参数说明
- -q:打印进程号
- -l:打印启动类的全限定名
- -m:打印启动类的 main 方法入参
- -v:打印指定的虚拟机参数
- -V:打印类名
JPS(全称:Java Virtual Machine Process Status Tool)。安装JDK后在%JAVA_HOME%/bin目录下面自带的一个工具。用来查看计算机上面运行的JAVA进程。(如下图) 在Linux机器上我一般使用的ps -aux|grep java
该工具只有16KB,所占内存很小。但是他会调用%JAVA_HOME%/lib/tools.jar里面的JAVA方法,来实现功能。
①jps -q 只显示进程号
C:\Users\Winston>jps -q
13476
2964
15224
9800
跟windows自带的任务管理器里面的PID就行比较,发现是一致的。此处windows进程里面少了一个。主要是少了我们当前运行的jps 命令。他也会发起一个java进程。
②jps -m
jps -m 显示传递给main方法的参数。针对嵌入式JVM可能输出null.
③ jps -l
显示运行程序主类的包名,或者运行程序jar包的完整路径。
④jps -v
打印指定的虚拟机参数
④jps -V
打印类名
2.Jstat
官网地址:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html#BEHBBBDJ
Jstat是JDK自带的一个轻量级小工具。全称“Java Virtual Machine statistics monitoring tool”,它位于java的bin目录下,主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。
每1秒,显示一下gc信息
jstat 用法
监视Java虚拟机(JVM)统计信息。此命令是实验性的,不受支持。
官网地址: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html 使用情况,参考文章链接:https://www.jianshu.com/p/213710fb9e40
- option:参数选项
- -t:可以在打印的列加上Timestamp列,用于显示系统运行的时间
- -h:可以在周期性数据数据的时候,可以在指定输出多少行以后输出一次表头
- vmid:Virtual Machine ID( 进程的 pid)
- interval:执行每次的间隔时间,单位为毫秒
- count:用于指定输出多少次记录,缺省则会一直打印
option 可以从下面参数中选择
- -class 显示ClassLoad的相关信息;
- -compiler 显示JIT编译的相关信息;
- -gc 显示和gc相关的堆信息;
- -gccapacity 显示各个代的容量以及使用情况;
- -gcmetacapacity 显示metaspace的大小
- -gcnew 显示新生代信息;
- -gcnewcapacity 显示新生代大小和使用情况;
- -gcold 显示老年代和永久代的信息;
- -gcoldcapacity 显示老年代的大小;
- -gcutil 显示垃圾收集信息;
- -gccause 显示垃圾回收的相关信息(通-gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因;
- -printcompilation 输出JIT编译的方法信息;
示例一:-class
显示加载class的数量,及所占空间等信息。
jstat -class <pid>
- Loaded : 已经装载的类的数量
- Bytes : 装载类所占用的字节数
- Unloaded:已经卸载类的数量
- Bytes:卸载类的字节数
- Time:装载和卸载类所花费的时间
示例二: -compiler
显示VM实时编译(JIT)的数量等信息。
jstat -compiler <pid>
- Compiled:编译任务执行数量
- Failed:编译任务执行失败数量
- Invalid :编译任务执行失效数量
- Time :编译任务消耗时间
- FailedType:最后一个编译失败任务的类型
- FailedMethod:最后一个编译失败任务所在的类及方法
示例三: -gc
显示gc相关的堆信息,查看gc的次数,及时间。
jstat –gc <pid>
- S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
- S0U :年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
- S1U :年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
- EC :年轻代中Eden(伊甸园)的容量 (字节)
- EU :年轻代中Eden(伊甸园)目前已使用空间 (字节)
- OC :Old代的容量 (字节)
- OU :Old代目前已使用空间 (字节)
- MC:metaspace(元空间)的容量 (字节)
- MU:metaspace(元空间)目前已使用空间 (字节)
- YGC :从应用程序启动到采样时年轻代中gc次数
- YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)
- FGC :从应用程序启动到采样时old代(全gc)gc次数
- FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
还可以间隔xx毫秒,打印x条记录,比如下面间隔250毫秒,打印10条数据。
jstat -gc 17360 250 10
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
10752.0 10752.0 0.0 3957.9 65536.0 7577.7 175104.0 144.0 18816.0 18379.0 2176.0 2082.2 1 0.023 0 0.000 0.023
10752.0 10752.0 0.0 3957.9 65536.0 7577.7 175104.0 144.0 18816.0 18379.0 2176.0 2082.2 1 0.023 0 0.000 0.023
10752.0 10752.0 0.0 3957.9 65536.0 7577.7 175104.0 144.0 18816.0 18379.0 2176.0 2082.2 1 0.023 0 0.000 0.023
10752.0 10752.0 0.0 3957.9 65536.0 7577.7 175104.0 144.0 18816.0 18379.0 2176.0 2082.2 1 0.023 0 0.000 0.023
10752.0 10752.0 0.0 3957.9 65536.0 7577.7 175104.0 144.0 18816.0 18379.0 2176.0 2082.2 1 0.023 0 0.000 0.023
10752.0 10752.0 0.0 3957.9 65536.0 7577.7 175104.0 144.0 18816.0 18379.0 2176.0 2082.2 1 0.023 0 0.000 0.023
10752.0 10752.0 0.0 3957.9 65536.0 7577.7 175104.0 144.0 18816.0 18379.0 2176.0 2082.2 1 0.023 0 0.000 0.023
10752.0 10752.0 0.0 3957.9 65536.0 7577.7 175104.0 144.0 18816.0 18379.0 2176.0 2082.2 1 0.023 0 0.000 0.023
10752.0 10752.0 0.0 3957.9 65536.0 7577.7 175104.0 144.0 18816.0 18379.0 2176.0 2082.2 1 0.023 0 0.000 0.023
10752.0 10752.0 0.0 3957.9 6553
示例四: -gccapacity
可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小
jstat -gccapacity <pid>
- NGCMN :年轻代(young)中初始化(最小)的大小(字节)
- NGCMX :年轻代(young)的最大容量 (字节)
- NGC :年轻代(young)中当前的容量 (字节)
- S0C :年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C : 年轻代中第二个survivor(幸存区)的容量 (字节)
- EC :年轻代中Eden(伊甸园)的容量 (字节)
- OGCMN :old代中初始化(最小)的大小 (字节)
- OGCMX :old代的最大容量(字节)
- OGC:old代当前新生成的容量 (字节)
- OC :Old代的容量 (字节)
- MCMN:metaspace(元空间)中初始化(最小)的大小 (字节)
- MCMX :metaspace(元空间)的最大容量 (字节)
- MC :metaspace(元空间)当前新生成的容量 (字节)
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC :从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时old代(全gc)gc次数
示例五:-gcmetacapacity
metaspace 中对象的信息及其占用量。
jstat -gcmetacapacity<pid>
- MCMN:最小元数据容量
- MCMX:最大元数据容量
- MC:当前元数据空间大小
- CCSMN:最小压缩类空间大小
- CCSMX:最大压缩类空间大小
- CCSC:当前压缩类空间大小
- YGC :从应用程序启动到采样时年轻代中gc次数
- FGC :从应用程序启动到采样时old代(全gc)gc次数
- FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
示例六: -gcnew
年轻代对象的信息。
jstat -gcnew <pid>
- S0C :年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C :年轻代中第二个survivor(幸存区)的容量 (字节)
- S0U :年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
- S1U :年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
- TT:持有次数限制
- MTT:最大持有次数限制
- DSS:期望的幸存区大小
- EC:年轻代中Eden(伊甸园)的容量 (字节)
- EU :年轻代中Eden(伊甸园)目前已使用空间 (字节)
- YGC :从应用程序启动到采样时年轻代中gc次数
- YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
示例七: -gcnewcapacity
年轻代对象的信息及其占用量
jstat -gcnewcapacity <pid>
- NGCMN :年轻代(young)中初始化(最小)的大小(字节)
- NGCMX :年轻代(young)的最大容量 (字节)
- NGC :年轻代(young)中当前的容量 (字节)
- S0CMX :年轻代中第一个survivor(幸存区)的最大容量 (字节)
- S0C :年轻代中第一个survivor(幸存区)的容量 (字节)
- S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)
- S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
- ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)
- EC:年轻代中Eden(伊甸园)的容量 (字节)
- YGC:从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时old代(全gc)gc次数
示例八: -gcold
old代对象的信息
jstat -gcold <pid>
- MC :metaspace(元空间)的容量 (字节)
- MU:metaspace(元空间)目前已使用空间 (字节)
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- OC:Old代的容量 (字节)
- OU:Old代目前已使用空间 (字节)
- YGC:从应用程序启动到采样时年轻代中gc次数
- FGC:从应用程序启动到采样时old代(全gc)gc次数
- FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
示例九:-gcoldcapacity
old代对象的信息及其占用量
jstat -gcoldcapacity <pid>
- OGCMN :old代中初始化(最小)的大小 (字节)
- OGCMX :old代的最大容量(字节)
- OGC :old代当前新生成的容量 (字节)
- OC :Old代的容量 (字节)
- YGC :从应用程序启动到采样时年轻代中gc次数
- FGC :从应用程序启动到采样时old代(全gc)gc次数
- FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
示例十: - gcutil
统计gc信息
jstat -gcutil <pid>
- S0 :年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
- S1 :年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
- E :年轻代中Eden(伊甸园)已使用的占当前容量百分比
- O :old代已使用的占当前容量百分比
- P :perm代已使用的占当前容量百分比
- YGC :从应用程序启动到采样时年轻代中gc次数
- YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)
- FGC :从应用程序启动到采样时old代(全gc)gc次数
- FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT:从应用程序启动到采样时gc用的总时间(s)
示例十一:-gccause
显示垃圾回收的相关信息(通-gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因。
jstat -gccause <pid>
- LGCC:最后一次GC原因
- GCC:当前GC原因(No GC 为当前没有执行GC)
示例十二: -printcompilation
当前VM执行的信息。
jstat -printcompilation <pid>
- Compiled :编译任务的数目
- Size :方法生成的字节码的大小
- Type:编译类型
- Method:类名和方法名用来标识编译的方法。类名使用/做为一个命名空间分隔符。方法名是给定类中的方法。上述格式是由-XX:+PrintComplation选项进行设置的.
3.Jinfo
jinfo 是 JDK 自带的命令,可以用来查看正在运行的 java 应用程序的扩展参数,包括Java System属性和JVM命令行参数;也可以动态的修改正在运行的 JVM 一些参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息.
官网地址:
<https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html>
jinfo用法:
参考博客地址:
<https://www.jianshu.com/p/8d8aef212b25>
jinfo 用法
jinfo 是 JDK 自带的命令,可以用来查看正在运行的 java 应用程序的扩展参数,包括Java System属性和JVM命令行参数;也可以动态的修改正在运行的 JVM 一些参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息.
参数说明
- pid 对应jvm的进程id
- executable core 产生core dump文件
- [server-id@]remote server IP or hostname 远程的ip或者hostname,server-id标记服务的唯一性id
option
- no option 输出全部的参数和系统属性
- -flag name 输出对应名称的参数
- -flag [+|-]name 开启或者关闭对应名称的参数
- -flag name=value 设定对应名称的参数
- -flags 输出全部的参数
- -sysprops 输出系统属性
Javacore 概述
Javacore,也可以称为“threaddump”或是“javadump”,它是 Java 提供的一种诊断特性,能够提供一份可读的当前运行的 JVM 中线程使用情况的快照。即在某个特定时刻,JVM 中有哪些线程在运行,每个线程执行到哪一个类,哪一个方法。
应用程序如果出现不可恢复的错误或是内存泄露,就会自动触发 Javacore 的生成。
示例一: no option
命令:jinfo pid
描述:输出当前 jvm 进程的全部参数和系统属性
示例二: -flag name
命令:jinfo -flag name pid
描述:输出对应名称的参数
使用该命令,可以查看指定的 jvm 参数的值。如:查看当前 jvm 进程是否开启打印 GC 日志。
示例三:-flag [+|-]name
命令:jinfo -flag [+|-]name pid
描述:开启或者关闭对应名称的参数
使用 jinfo 可以在不重启虚拟机的情况下,可以动态的修改 jvm 的参数。尤其在线上的环境特别有用。
使用如下:
示例四:-flag name=value
命令:jinfo -flag name=value pid
描述:修改指定参数的值。
同示例三,但示例三主要是针对 boolean 值的参数设置的。
如果是设置 value值,则需要使用 name=value 的形式。
使用如下:
注意事项 :
jinfo虽然可以在java程序运行时动态地修改虚拟机参数,但并不是所有的参数都支持动态修改
示例五: -flags
命令:jinfo -flags pid
描述:输出全部的参数
示例六:-sysprops
命令:jinfo -sysprops pid
描述:输出当前 jvm 进行的全部的系统属性
4.jmap
官网地址:<https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html>
概述
命令jmap是一个多功能的命令。它可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列。
jmap 用法
参考文章:https://www.jianshu.com/p/a4ad53179df3
参数:
- option:选项参数。
- pid:需要打印配置信息的进程ID。
- executable:产生核心dump的Java可执行文件。
- core:需要打印配置信息的核心文件。
- server-id可选的唯一id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器。
- remote server IP or hostname远程调试服务器的IP地址或主机名。
option
- no option:查看进程的内存映像信息,类似 Solaris pmap 命令。
- heap:显示Java堆详细信息
- histo[:live]:显示堆中对象的统计信息
- **clstats:**打印类加载器信息
- finalizerinfo:显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
- **dump::**生成堆转储快照
- F:当-dump没有响应时,使用-dump或者-histo参数. 在这个模式下,live子参数无效.
- **help:**打印帮助信息
- **J:**指定传递给运行jmap的JVM的参数
示例一:no option
命令:jmap pid
描述:查看进程的内存映像信息,类似 Solaris pmap 命令。
使用不带选项参数的jmap打印共享对象映射,将会打印目标虚拟机中加载的每个共享对象的起始地址、映射大小以及共享对象文件的路径全称。这与Solaris的pmap工具比较相似。
示例二:heap
命令:jmap -heap pid
描述:显示Java堆详细信息
打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和各内存区域内存使用信息
C:\Users\jjs>jmap -heap 5932
Attaching to process ID 5932, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.91-b15
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 1073741824 (1024.0MB)
NewSize = 42991616 (41.0MB)
MaxNewSize = 357564416 (341.0MB)
OldSize = 87031808 (83.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 60293120 (57.5MB)
used = 44166744 (42.120689392089844MB)
free = 16126376 (15.379310607910156MB)
73.25337285580842% used
From Space:
capacity = 5242880 (5.0MB)
used = 0 (0.0MB)
free = 5242880 (5.0MB)
0.0% used
To Space:
capacity = 14680064 (14.0MB)
used = 0 (0.0MB)
free = 14680064 (14.0MB)
0.0% used
PS Old Generation
capacity = 120061952 (114.5MB)
used = 19805592 (18.888084411621094MB)
free = 100256360 (95.6119155883789MB)
16.496143590935453% used
20342 interned Strings occupying 1863208 bytes.
示例三:histo[:live]
命令:jmap -histo:live pid
描述:显示堆中对象的统计信息
其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果指定了live子选项,则只计算活动的对象。
示例四:clstats
命令:jmap -clstats pid
描述:打印类加载器信息
-clstats是-permstat的替代方案,在JDK8之前,-permstat用来打印类加载器的数据
打印Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。
示例五:finalizerinfo
命令:jmap -finalizerinfo pid
描述:打印等待终结的对象信息
Number of objects pending for finalization: 0 说明当前F-QUEUE队列中并没有等待Fializer线程执行final
示例六:dump:
命令:jmap -dump:format=b,file=heapdump.phrof pid
描述:生成堆转储快照dump文件。
以hprof二进制格式转储Java堆到指定filename的文件中。live子选项是可选的。如果指定了live子选项,堆中只有活动的对象会被转储。想要浏览heap dump,你可以使用jhat(Java堆分析工具)读取生成的文件。
这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用, 线上系统慎用。
5.jhat
官网:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jhat.html
该jhat
命令解析Java堆转储文件并启动Web服务器。该jhat
命令使您可以使用自己喜欢的Web浏览器浏览堆转储。该jhat
命令支持预先设计的查询,例如显示已知类的所有实例MyClass
以及对象查询语言(OQL)。OQL与SQL类似,除了查询堆转储。可从jhat
命令显示的OQL帮助页面获得有关OQL的帮助。使用默认端口,可以从http//localhost:7000/oqlhelp /获得OQL帮助。
案例:
1.导出dump信息到a.bin文件
2.启动jhat进行分析文件
3.浏览器查看
- Heap Histogram
- OQL
6.jstack
官方地址:
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstack.html
jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中线程堆栈信息。
例子:
- 高手是如何用jstack找到异常代码的
- jvm 性能调优工具之 jstack(用法+死锁案例)
演示:
方式1:直接查看堆栈信息
方式2:
java用thread的api有个方法:Thread.getAllStackTraces().也可以查看堆栈信息。
打印结果如下:
二、可视化工具
1.jconsole
该jconsole
命令启动图形控制台工具,使您可以监视和管理本地或远程计算机上的Java应用程序和虚拟机。
官网地址:<https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jconsole.html>
①内存监控
写个demo测试下:
public class JconsoleTest {
public byte[] b1 = new byte[128 * 1024];
public static void main(String[] args) {
try {
Thread.sleep(5000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("start ..");
fill(1000);
}
private static void fill(int n) {
ArrayList<JconsoleTest> jlist = new ArrayList<>();
for (int i=0;i<n;i++){
try {
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
jlist.add(new JconsoleTest());
}
}
}
cmd中输入jconsole
查看堆和线程等信息的变化:
②线程监控
public class Main {
public static void main(String[] args) {
//创建一个输入流,让程序卡在这里
Scanner sc = new Scanner(System.in);
sc.next();
new Thread(new Runnable() {
@Override
public void run() {
while(true){
}
}
},"while true线程").start();
sc.next();
testWait(new Object());
}
private static void testWait(Object obj) {
System.out.println("----testWait-------");
new Thread(new Runnable() {
@Override
public void run() {
synchronized (obj){
try {
obj.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
},"testWait 线程").start();
}
}
- 监控输入流的线程
- 监控runnable线程
- 监控wait线程
③线程死锁监控
测试代码
public class DeadLock implements Runnable {
private Object obj1;
private Object obj2;
public DeadLock(Object obj1, Object obj2) {
this.obj1 = obj1;
this.obj2 = obj2;
}
@Override
public void run() {
synchronized (obj1){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj2){
System.out.println("Hello");
}
}
}
}
public class Main {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
new Thread(new DeadLock(obj1, obj2)).start();
new Thread(new DeadLock(obj2, obj1)).start();
}
}
使用jconsole查看
点击检测死锁
2.visualVM
VisualVM是一个以监控、显示本地或者远程服务器 JVM工作情况,进行性能调优的工具。借助VisualVM,我们可以实现对JVM内存各个子池、CPU、垃圾收集器等方面进行监控,从而发现程序代码中潜在的泄露点和配置问题。
VisualVM是一个Java编写的绿色软件,属于开源范畴。VisualVM是使用插件Plugin的方式提供功能,默认提供了一些基本检测功能。如果需要进行拓展,可以使用下载插件的功能进行。
下载地址: https://visualvm.github.io/index.html
插件下载地址:https://visualvm.github.io/pluginscenters.html
①安装:
安装完毕,打开exe
如果打开了idea或者eclipse,可以在左侧菜单栏看到:
可以看到,各种idea的各种信息
②插件下载
可以用这个地址:
插件下载地址:<https://visualvm.github.io/pluginscenters.html
也可以:
在线安装:
完