文章目录

1.jps :jdk中自带的工具

1.1.概念

jps(Java Virtual Machine Process Status Tool)

我们这里通过下面的这个springboot项目的启动脚本去分析 jps不同命令的输出

./copy-gh-third.jar.sh
export JAVA_HOME=/weblogic/jdk1.8.0_181
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
java -jar -Xmx512m -Xms256m -Duser.timezone=GMT+8:00 gh-third.jar --spring.profiles.active=prd --server.port=7001 --dubbo.registry.group=dubbo/prd >> /weblogic/bea/user_projects/domains/third/logs/wls.log 2>&1 &
echo "gh-third-spring-boot starting ..."

1.2.jps -q :只输出进程 ID

JVM之jdk自带的常用工具命令_ide_02

1.3.jps -m :输出传入 main 方法的参数

JVM之jdk自带的常用工具命令_java_03

1.4.jps -l :输出完全的包名,应用主类名,jar的完全路径名

[weblogic@iZzm07uu28d7wcuv8t6ms3Z third]$ jps -l
34124 gh-third.jar
47089 sun.tools.jps.Jps
[weblogic@iZzm07uu28d7wcuv8t6ms3Z third]$

1.5.jps -v :输出jvm参数

[weblogic@iZzm07uu28d7wcuv8t6ms3Z third]$ jps -v
47877 Jps -Dapplication.home=/weblogic/jdk1.7.0_80 -Xms8m
34124 jar -Xmx512m -Xms256m -Duser.timezone=GMT+8:00
[weblogic@iZzm07uu28d7wcuv8t6ms3Z third]$

2.jinfo:jdk中自带的工具

2.1.概念

1.jinfo主要是打印java虚拟机的参数以及动态修改java虚拟机参数
2.jinfo使用,一般是与上面jps一起使用的,因为jinfo的使用需要知道进程的ip(process id),当然如果你有其他方式可以知道进程的id
也是可以替代jps的使用的;

2.2.查看某个进程的某个属性的值:jinfo -flag ${jvm-property-name} ${pid}

jinfo -flag MaxHeapSize 19337 查看进程19337 最大堆内存设置

[weblogic@10_32_69_84 ~]$ jps -ml
19337 gh-third.jar --spring.profiles.active=dat --server.port=7005 --dubbo.registry.group=dubbo/dat --debug
27875 weblogic.Server
6284 sun.tools.jps.Jps -ml
20458 weblogic.Server
[weblogic@10_32_69_84 ~]$
[weblogic@10_32_69_84 ~]$ jinfo -flag MaxHeapSize 19337
-XX:MaxHeapSize=2147483648
[weblogic@10_32_69_84 ~]$

2.3.查看某个进程的所有属性的值:jinfo -flags ${pid}

2.4.修改某个进程的所有属性的值:jinfo -flag [+/-] ${jvm-property-name} ${pid}

这里注意下,只有标记位manageable的属性才可以被修改

JVM之jdk自带的常用工具命令_java_04


设置

localhost:~ gaoxinfu$ jps -ml
66626 sun.tools.jps.Jps -ml
63910 org.jetbrains.idea.maven.server.RemoteMavenServer
63720
66569 org.jetbrains.jps.cmdline.Launcher /Applications/IntelliJ IDEA.app/Contents/lib/plexus-component-annotations-1.6.jar:/Applications/IntelliJ IDEA.app/Contents/lib/asm-all-7.0.1.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-api-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-transport-http-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-util-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/lz4-1.3.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/httpcore-4.4.10.jar:/Applications/IntelliJ IDEA.app/Contents/lib/netty-buffer-4.1.32.Final.jar:/Applications/IntelliJ IDEA.app/Contents/lib/guava-25.1-jre.jar:/Applications/IntelliJ IDEA.app/Contents/lib/netty-transport-4.1.32.Final.jar:/Applications/IntelliJ IDEA.app/Contents/lib/util.jar:/Applications/IntelliJ IDEA.app/Contents/lib/platform-api.jar:/Applications/IntelliJ IDEA.app/Contents/lib/plexus-interpolation-1.21.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-spi-1.1.0.jar:/Applications/IntelliJ IDEA.app/Cont
66570 com.gaoxinfu.demo.jvm.DemoJvmApplication
localhost:~ gaoxinfu$ jinfo -flag +HeapDumpAfterFullGC 66570
localhost:~

查看 +HeapDumpAfterFullGC 标示已经开启了

localhost:~ gaoxinfu$ jinfo -flag HeapDumpAfterFullGC 66570
-XX:+HeapDumpAfterFullGC
localhost:~

2.5.修改某个进程的所有属性的值:jinfo -flag j v m − p r o p e r t y − n a m e = {jvm-property-name}= jvm−property−name={value} ${pid}

JVM之jdk自带的常用工具命令_ide_05


设置

localhost:~ gaoxinfu$ jps -ml
66626 sun.tools.jps.Jps -ml
63910 org.jetbrains.idea.maven.server.RemoteMavenServer
63720
66569 org.jetbrains.jps.cmdline.Launcher /Applications/IntelliJ IDEA.app/Contents/lib/plexus-component-annotations-1.6.jar:/Applications/IntelliJ IDEA.app/Contents/lib/asm-all-7.0.1.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-api-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-transport-http-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-util-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/lz4-1.3.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/httpcore-4.4.10.jar:/Applications/IntelliJ IDEA.app/Contents/lib/netty-buffer-4.1.32.Final.jar:/Applications/IntelliJ IDEA.app/Contents/lib/guava-25.1-jre.jar:/Applications/IntelliJ IDEA.app/Contents/lib/netty-transport-4.1.32.Final.jar:/Applications/IntelliJ IDEA.app/Contents/lib/util.jar:/Applications/IntelliJ IDEA.app/Contents/lib/platform-api.jar:/Applications/IntelliJ IDEA.app/Contents/lib/plexus-interpolation-1.21.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-spi-1.1.0.jar:/Applications/IntelliJ IDEA.app/Cont
66570 com.gaoxinfu.demo.jvm.DemoJvmApplication
localhost:~ gaoxinfu$ jinfo -flag CMSWaitDuration=3000 66570
localhost:~

查看

localhost:~ gaoxinfu$ jinfo -flag CMSWaitDuration 66570
-XX:CMSWaitDuration=3000
localhost:~

3.jstat

官网使用地址介绍
​​​https://docs.oracle.com/javase/9/tools/jstat.htm#JSWOR734​

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。
命令的格式如下:
jstat [-命令选项类型] [pid] [间隔时间/毫秒] [查询次数]
这里注意下 [间隔时间/毫秒] [查询次数] 这些是可选的,意味着不写,只会输出一次;

3.1.类加载信息:jstat -class 66570 1000 10

localhost:~ gaoxinfu$ jps -ml
63910 org.jetbrains.idea.maven.server.RemoteMavenServer
63720
66569 org.jetbrains.jps.cmdline.Launcher /Applications/IntelliJ IDEA.app/Contents/lib/plexus-component-annotations-1.6.jar:/Applications/IntelliJ IDEA.app/Contents/lib/asm-all-7.0.1.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-api-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-transport-http-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-util-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/lz4-1.3.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/httpcore-4.4.10.jar:/Applications/IntelliJ IDEA.app/Contents/lib/netty-buffer-4.1.32.Final.jar:/Applications/IntelliJ IDEA.app/Contents/lib/guava-25.1-jre.jar:/Applications/IntelliJ IDEA.app/Contents/lib/netty-transport-4.1.32.Final.jar:/Applications/IntelliJ IDEA.app/Contents/lib/util.jar:/Applications/IntelliJ IDEA.app/Contents/lib/platform-api.jar:/Applications/IntelliJ IDEA.app/Contents/lib/plexus-interpolation-1.21.jar:/Applications/IntelliJ IDEA.app/Contents/lib/aether-spi-1.1.0.jar:/Applications/IntelliJ IDEA.app/Cont
66570 com.gaoxinfu.demo.jvm.DemoJvmApplication
74511 sun.tools.jps.Jps -ml
localhost:~ gaoxinfu$ jstat -class 66570 1000 10
Loaded Bytes Unloaded Bytes Time
6339 11588.7 0 0.0 5.89
6339 11588.7 0 0.0 5.89
6339 11588.7 0 0.0 5.89
6339 11588.7 0 0.0 5.89
6339 11588.7 0 0.0 5.89
6339 11588.7 0 0.0 5.89
6339 11588.7 0 0.0 5.89
6339 11588.7 0 0.0 5.89
6339 11588.7 0 0.0 5.89
6339 11588.7 0 0.0 5.89
localhost:~
Loaded:加载class的数量
Bytes:所占用空间大小
Unloaded:未加载数量
Bytes:未加载占用空间
Time:时间

3.2.垃圾回收:jstat -gc 66570 1000 5

localhost:~ gaoxinfu$ jstat -gc 66570 1000 5
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
9728.0 11264.0 9721.8 0.0 45568.0 6382.5 68608.0 9036.8 34688.0 32983.1 4480.0 4172.8 8 0.065 1 0.050 0.115
9728.0 11264.0 9721.8 0.0 45568.0 6382.5 68608.0 9036.8 34688.0 32983.1 4480.0 4172.8 8 0.065 1 0.050 0.115
9728.0 11264.0 9721.8 0.0 45568.0 6382.5 68608.0 9036.8 34688.0 32983.1 4480.0 4172.8 8 0.065 1 0.050 0.115
9728.0 11264.0 9721.8 0.0 45568.0 6382.5 68608.0 9036.8 34688.0 32983.1 4480.0 4172.8 8 0.065 1 0.050 0.115
9728.0 11264.0 9721.8 0.0 45568.0 6382.5 68608.0 9036.8 34688.0 32983.1 4480.0 4172.8 8 0.065 1 0.050 0.115
localhost:~
S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

3.3.堆内存统计:jstat -gccapacity 66570 1000 5

localhost:~ gaoxinfu$ jstat -gccapacity 66570 1000 5
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
33792.0 68096.0 68096.0 9728.0 11264.0 45568.0 68608.0 136704.0 68608.0 68608.0 0.0 1079296.0 34688.0 0.0 1048576.0 4480.0 8 1
33792.0 68096.0 68096.0 9728.0 11264.0 45568.0 68608.0 136704.0 68608.0 68608.0 0.0 1079296.0 34688.0 0.0 1048576.0 4480.0 8 1
33792.0 68096.0 68096.0 9728.0 11264.0 45568.0 68608.0 136704.0 68608.0 68608.0 0.0 1079296.0 34688.0 0.0 1048576.0 4480.0 8 1
33792.0 68096.0 68096.0 9728.0 11264.0 45568.0 68608.0 136704.0 68608.0 68608.0 0.0 1079296.0 34688.0 0.0 1048576.0 4480.0 8 1
33792.0 68096.0 68096.0 9728.0 11264.0 45568.0 68608.0 136704.0 68608.0 68608.0 0.0 1079296.0 34688.0 0.0 1048576.0 4480.0 8 1
localhost:~
NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
EC:伊甸园区的大小
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:当前老年代大小
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代gc次数
FGC:老年代GC次数

3.4.新生代垃圾回收统计:jstat -gcnew 66570

localhost:~ gaoxinfu$ jstat -gcnew 66570
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
9728.0 11264.0 9721.8 0.0 6 15 11264.0 45568.0 7293.9 8 0.065
localhost:~
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
TT:对象在新生代存活的次数
MTT:对象在新生代存活的最大次数
DSS:期望的幸存区大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间

3.5.新生代内存统计:jstat -gcnewcapacity 66570

localhost:~ gaoxinfu$ jstat -gcnewcapacity 66570
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
33792.0 68096.0 68096.0 22528.0 9728.0 22528.0 11264.0 67072.0 45568.0 8 1
localhost:~
NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0CMX:最大幸存1区大小
S0C:当前幸存1区大小
S1CMX:最大幸存2区大小
S1C:当前幸存2区大小
ECMX:最大伊甸园区大小
EC:当前伊甸园区大小
YGC:年轻代垃圾回收次数
FGC:老年代回收次数

3.6.老年代垃圾回收统计:jstat -gcold 66570

localhost:~ gaoxinfu$ jstat -gcold 66570
MC MU CCSC CCSU OC OU YGC FGC FGCT GCT
34688.0 32983.1 4480.0 4172.8 68608.0 9036.8 8 1 0.050 0.115
localhost:~
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
OC:老年代大小
OU:老年代使用大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

3.7.老年代内存统计:jstat -gcoldcapacity 66570

localhost:~ gaoxinfu$ jstat -gcoldcapacity 66570
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
68608.0 136704.0 68608.0 68608.0 8 1 0.050 0.115
localhost:~
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:老年代大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

3.8.JDK8 下 元数据空间统计:

localhost:~ gaoxinfu$ jstat -gcmetacapacity 66570
MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT
0.0 1079296.0 34688.0 0.0 1048576.0 4480.0 8 1 0.050 0.115
localhost:~
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

4.jstack :查看线程的堆栈信息

4.1.概念

Prints Java thread stack traces for a Java process, core file, or remote debug server. This command is experimental and unsupported.

打印当前应用进程|文件|远程调试的服务的Java线程的栈信息情况

格式

jstack [pid]

4.2.jstack 66570

localhost:~ gaoxinfu$ jps 
72514 Jstat
63720
66569 Launcher
66570 DemoJvmApplication
23726 Jps
72639 Jstat
localhost:~ gaoxinfu$ jstack 66570
2020-03-12 10:26:13
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.211-b12 mixed mode):

"Attach Listener" #33 daemon prio=9 os_prio=31 tid=0x00007fe3eefed000 nid=0x9c03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #32 prio=5 os_prio=31 tid=0x00007fe3eff71000 nid=0xe03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"http-nio-8080-Acceptor" #30 daemon prio=5 os_prio=31 tid=0x00007fe3eff6f000 nid=0x6103 runnable [0x000070000cb4c000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
- locked <0x00000007bbe10240> (a java.lang.Object)
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:463)
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:73)
at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:95)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-ClientPoller" #29 daemon prio=5 os_prio=31 tid=0x00007fe3edff7000 nid=0x9e03 runnable [0x000070000ca49000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method)
at sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:198)
at sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:117)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000007bbf5dd10> (a sun.nio.ch.Util$3)
- locked <0x00000007bbf5dd00> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000007bbf5dbe0> (a sun.nio.ch.KQueueSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:708)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-10" #28 daemon prio=5 os_prio=31 tid=0x00007fe3edff2000 nid=0x6003 waiting on condition [0x000070000c946000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bbec15b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-9" #27 daemon prio=5 os_prio=31 tid=0x00007fe3eefee800 nid=0xa103 waiting on condition [0x000070000c843000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bbec15b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-8" #26 daemon prio=5 os_prio=31 tid=0x00007fe3ecfab000 nid=0x5e03 waiting on condition [0x000070000c740000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bbec15b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-7" #25 daemon prio=5 os_prio=31 tid=0x00007fe3ecdac000 nid=0x5c03 waiting on condition [0x000070000c63d000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bbec15b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-6" #24 daemon prio=5 os_prio=31 tid=0x00007fe3eefee000 nid=0xa303 waiting on condition [0x000070000c53a000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bbec15b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-5" #23 daemon prio=5 os_prio=31 tid=0x00007fe3ecdab000 nid=0x5b03 waiting on condition [0x000070000c437000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bbec15b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-4" #22 daemon prio=5 os_prio=31 tid=0x00007fe3ece7e800 nid=0x5a03 waiting on condition [0x000070000c334000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bbec15b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-3" #21 daemon prio=5 os_prio=31 tid=0x00007fe3efe26800 nid=0xa603 waiting on condition [0x000070000c231000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bbec15b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-2" #20 daemon prio=5 os_prio=31 tid=0x00007fe3ecff7000 nid=0xa803 waiting on condition [0x000070000c12e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bbec15b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-1" #19 daemon prio=5 os_prio=31 tid=0x00007fe3eef4b000 nid=0x5703 waiting on condition [0x000070000c02b000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bbec15b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:107)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-BlockPoller" #18 daemon prio=5 os_prio=31 tid=0x00007fe3ee960800 nid=0x4e0b runnable [0x000070000bf28000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method)
at sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:198)
at sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:117)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000007bbe3a3a8> (a sun.nio.ch.Util$3)
- locked <0x00000007bbe39300> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000007bbe39178> (a sun.nio.ch.KQueueSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:313)

"container-0" #17 prio=5 os_prio=31 tid=0x00007fe3eddd0000 nid=0x5503 waiting on condition [0x000070000be25000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.catalina.core.StandardServer.await(StandardServer.java:570)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer$1.run(TomcatWebServer.java:179)

"Catalina-utility-2" #16 prio=1 os_prio=31 tid=0x00007fe3eaecd000 nid=0x4207 waiting on condition [0x000070000bd22000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bf8819b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"Catalina-utility-1" #15 prio=1 os_prio=31 tid=0x00007fe3ea755000 nid=0x4407 waiting on condition [0x000070000bc1f000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007bf8819b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

"Service Thread" #11 daemon prio=9 os_prio=31 tid=0x00007fe3eb095800 nid=0x4603 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #10 daemon prio=9 os_prio=31 tid=0x00007fe3ea8bd800 nid=0x4703 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #9 daemon prio=9 os_prio=31 tid=0x00007fe3ea8bc800 nid=0x4803 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #8 daemon prio=9 os_prio=31 tid=0x00007fe3ea8bc000 nid=0x3b03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"JDWP Command Reader" #7 daemon prio=10 os_prio=31 tid=0x00007fe3eb83e000 nid=0x4903 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"JDWP Event Helper Thread" #6 daemon prio=10 os_prio=31 tid=0x00007fe3ea01d800 nid=0x3803 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"JDWP Transport Listener: dt_socket" #5 daemon prio=10 os_prio=31 tid=0x00007fe3ea01c800 nid=0x3707 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007fe3ea00c800 nid=0x4b03 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fe3ea003000 nid=0x2e03 in Object.wait() [0x000070000b0fb000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007b3cc01c0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x00000007b3cc01c0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)

"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fe3ea816000 nid=0x5403 in Object.wait() [0x000070000aff8000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007b3cd0b68> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000007b3cd0b68> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=31 tid=0x00007fe3ea002000 nid=0x2c03 runnable

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fe3eb004800 nid=0x2407 runnable

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fe3ea803000 nid=0x2303 runnable

"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fe3eb80d000 nid=0x2103 runnable

"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fe3eb808800 nid=0x2a03 runnable

"VM Periodic Task Thread" os_prio=31 tid=0x00007fe3ea0f0000 nid=0x4503 waiting on condition

JNI global references: 16314

localhost:~

4.3.适用场景

1.线程死锁等问题发生时,方便排查;

4.4.案例说明

4.4.1.代码

代码地址
​​​https://gitee.com/gaoxinfu_admin/demo-jdk/blob/master/demo-jvm/src/main/java/com/gaoxinfu/demo/jvm/jstack/DeadLockDemo.java​

package com.gaoxinfu.demo.jvm.jstack;

//运行主类
public class DeadLockDemo
{
public static void main(String[] args)
{
DeadLock d1=new DeadLock(true);
DeadLock d2=new DeadLock(false);
Thread t1=new Thread(d1);
Thread t2=new Thread(d2);
t1.start();
t2.start();
}
}
//定义锁对象
class MyLock{
public static Object obj1=new Object();
public static Object obj2=new Object();
}
//死锁代码
class DeadLock implements Runnable{
private boolean flag;
DeadLock(boolean flag){
this.flag=flag;
}
public void run() {
if(flag) {
while(true) {
synchronized(MyLock.obj1) {
System.out.println(Thread.currentThread().getName()+"----if获得obj1锁");
synchronized(MyLock.obj2) {
System.out.println(Thread.currentThread().getName()+"----if获得obj2锁");
}
}
}
}
else {
while(true){
synchronized(MyLock.obj2) {
System.out.println(Thread.currentThread().getName()+"----否则获得obj2锁");
synchronized(MyLock.obj1) {
System.out.println(Thread.currentThread().getName()+"----否则获得obj1锁");

}
}
}
}
}
}

4.4.2.运行DeadLockDemo的main方法

JVM之jdk自带的常用工具命令_ide_06

1.从上面,我们看到线程0和线程1相互之间已经锁定,无法获得锁,导致无法继续往下进行

4.4.3.通过jstack查看具体的问题

localhost:~ gaoxinfu$ jps
29472 Launcher
72514 Jstat
29475 DeadLockDemo
28931 RemoteMavenServer
63720
72639 Jstat
29567 Jps
localhost:~ gaoxinfu$ jstack 29475
2020-03-12 10:47:51
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.211-b12 mixed mode):

"Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007fec318d6800 nid=0x3c03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #12 prio=5 os_prio=31 tid=0x00007fec32152000 nid=0xe03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Thread-1" #11 prio=5 os_prio=31 tid=0x00007fec30908000 nid=0x4003 waiting for monitor entry [0x0000700003fa4000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.gaoxinfu.demo.jvm.jstack.DeadLock.run(DeadLockDemo.java:43)
- waiting to lock <0x00000007958204a8> (a java.lang.Object)
- locked <0x00000007958204b8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)

"Thread-0" #10 prio=5 os_prio=31 tid=0x00007fec32151800 nid=0x3903 waiting for monitor entry [0x0000700003ea1000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.gaoxinfu.demo.jvm.jstack.DeadLock.run(DeadLockDemo.java:33)
- waiting to lock <0x00000007958204b8> (a java.lang.Object)
- locked <0x00000007958204a8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)

"Service Thread" #9 daemon prio=9 os_prio=31 tid=0x00007fec310b4000 nid=0x3703 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007fec3088b800 nid=0x3503 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007fec30878800 nid=0x4403 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007fec30877800 nid=0x3403 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007fec31805000 nid=0x4703 runnable [0x000070000388f000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x00000007957b2eb0> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
- locked <0x00000007957b2eb0> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007fec31023000 nid=0x4803 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fec3101b800 nid=0x2c03 in Object.wait() [0x0000700003583000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000795588ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x0000000795588ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)

"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fec3101b000 nid=0x5203 in Object.wait() [0x0000700003480000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000795586bf8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x0000000795586bf8> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=31 tid=0x00007fec31018000 nid=0x2b03 runnable

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fec31809800 nid=0x2007 runnable

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fec31006000 nid=0x2403 runnable

"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fec31006800 nid=0x2303 runnable

"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fec32000800 nid=0x2a03 runnable

"VM Periodic Task Thread" os_prio=31 tid=0x00007fec31024000 nid=0x4203 waiting on condition

JNI global references: 15


Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007fec320283e8 (object 0x00000007958204a8, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x00007fec32025cb8 (object 0x00000007958204b8, a java.lang.Object),
which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
at com.gaoxinfu.demo.jvm.jstack.DeadLock.run(DeadLockDemo.java:43)
- waiting to lock <0x00000007958204a8> (a java.lang.Object)
- locked <0x00000007958204b8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
"Thread-0":
at com.gaoxinfu.demo.jvm.jstack.DeadLock.run(DeadLockDemo.java:33)
- waiting to lock <0x00000007958204b8> (a java.lang.Object)
- locked <0x00000007958204a8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

localhost:~

JVM之jdk自带的常用工具命令_jar_07

1.从上面我们知道发现了一个死锁;
2.线程1在等待获取锁0x00000007958204a8,但是0x00000007958204a8被线程0已经锁定
线程0在等待获取锁0x00000007958204b8,但是0x00000007958204b8被线程1已经锁定
这样接下来,我们通过上面的分析,可以定位的代码的问题,从而去优化处理;

5.jmap 查看堆内存的相关信息

5.1.查看指定进程的堆内存相关信息设置: jmap -heap 90844

5.1.1.格式: jmap -heap ${pid}

5.1.2.异常: Can’t attach symbolicator to the process

localhost:libexec gaoxinfu$ java -version
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
localhost:libexec gaoxinfu$ jps
72514 Jstat
63720
90843 Launcher
90923 Jps
90844 DemoJvmApplication
72639 Jstat
localhost:libexec gaoxinfu$ jmap -heap 90844
Attaching to process ID 90844, please wait...
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach symbolicator to the process
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: Can't attach symbolicator to the process
at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal$BsdDebuggerLocalWorkerThread.execute(BsdDebuggerLocal.java:169)
at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal.attach(BsdDebuggerLocal.java:287)
at sun.jvm.hotspot.HotSpotAgent.attachDebugger(HotSpotAgent.java:671)
at sun.jvm.hotspot.HotSpotAgent.setupDebuggerDarwin(HotSpotAgent.java:659)
at sun.jvm.hotspot.HotSpotAgent.setupDebugger(HotSpotAgent.java:341)
at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:304)
at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:185)
at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
at sun.jvm.hotspot.tools.HeapSummary.main(HeapSummary.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.tools.jmap.JMap.runTool(JMap.java:201)
at sun.tools.jmap.JMap.main(JMap.java:130)
Caused by: sun.jvm.hotspot.debugger.DebuggerException: Can't attach symbolicator to the process
at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal.attach0(Native Method)
at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal.access$100(BsdDebuggerLocal.java:65)
at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal$1AttachTask.doit(BsdDebuggerLocal.java:278)
at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal$BsdDebuggerLocalWorkerThread.run(BsdDebuggerLocal.java:144)

localhost:libexec gaoxinfu$

5.1.2.正常的 TODO

JVM之jdk自带的常用工具命令_java_08

5.1.3.命令行格式:将堆内存输出到文件中

5.1.3.1.格式:jmap -dump:format=b,file=heap.hprof 93325

jmap -dump:format=b,file=${文件名} ${进程ID}
jmap -dump:format=b 固定格式

5.1.3.2.演示

localhost:libexec gaoxinfu$ jps
72514 Jstat
93445 Jps
63720
93325 DemoJvmApplication
93324 Launcher
72639 Jstat
localhost:libexec gaoxinfu$ jmap -dump:format=b,file=heap.hprof 93325
Dumping heap to /usr/libexec/heap.hprof ...
Operation not permitted
localhost:libexec gaoxinfu$ pwd
/usr/libexec
localhost:libexec gaoxinfu$ cd ~
localhost:~ gaoxinfu$ jmap -dump:format=b,file=heap.hprof 93325
Dumping heap to /Users/gaoxinfu/heap.hprof ...
Heap dump file created
localhost:~ gaoxinfu$ pwd
/Users/gaoxinfu
localhost:~

JVM之jdk自带的常用工具命令_ide_09

关于上面生成的heap.hprof文件查看,我们后面通过工具去查看,暂时不做介绍

5.1.3.开发工具方式(Idea):发生内存溢出的时候,将堆内存输出到文件中

5.1.3.1.设置参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof

**-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof **

-XX:+PrintFlagsFinal -Xms1M -Xmx10M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof
-XX:+PrintFlagsFinal 启动打印全部jvm参数
-Xms1M -Xmx10M :堆内存设置最小1M,最大10M
-XX:+HeapDumpOnOutOfMemoryError 开启堆内存溢出的时候做某些操作
-XX:HeapDumpPath=heap.hprof 溢出时,输出到文件中

JVM之jdk自带的常用工具命令_ide_10

5.1.3.2.请求模拟内存溢出

​http://localhost:8080/heap​

JVM之jdk自带的常用工具命令_jar_11

5.1.3.3.文件生成成功

JVM之jdk自带的常用工具命令_ide_12