JVM优化篇章一
1.jvm运行参数
三种参数类型
1.1 标准参数
-help
-version
jvm的标准参数,一般都是很稳定的,在未来的JVM版本中不会改变,可以使用java -help检索出所有的标准参数。
C:\Users\CYJ>java -help
用法: java [-options] class [args...] (执行类)
或 java [-options] -jar jarfile [args...] (执行 jar 文件)
其中选项包括:
-d32 使用 32 位数据模型 (如果可用)
-d64 使用 64 位数据模型 (如果可用)
-server 选择 "server" VM 默认 VM 是 server.
-cp <目录和 zip/jar 文件的类搜索路径>
-classpath <目录和 zip/jar 文件的类搜索路径>
用 ; 分隔的目录, JAR 档案
和 ZIP 档案列表, 用于搜索类文件。
-D<名称>=<值> 设置系统属性
-verbose:[class|gc|jni] 启用详细输出
-version 输出产品版本并退出
-version:<值> 警告: 此功能已过时, 将在未来发行版中删除。需要指定的版本才能运行
-showversion 输出产品版本并继续
-jre-restrict-search | -no-jre-restrict-search
警告: 此功能已过时, 将在未来发行版中删除。在版本搜索中包括/排除用户专用 JRE
-? -help 输出此帮助消息
-X 输出非标准选项的帮助
-ea[:<packagename>...|:<classname>]
-enableassertions[:<packagename>...|:<classname>]
按指定的粒度启用断言
-da[:<packagename>...|:<classname>]
-disableassertions[:<packagename>...|:<classname>]
禁用具有指定粒度的断言
-esa | -enablesystemassertions 启用系统断言
-dsa | -disablesystemassertions 禁用系统断言
-agentlib:<libname>[=<选项>]
加载本机代理库 <libname>, 例如 -agentlib:hprof
另请参阅 -agentlib:jdwp=help 和 -agentlib:hprof=help
-agentpath:<pathname>[=<选项>] 按完整路径名加载本机代理库
-javaagent:<jarpath>[=<选项>] 加载 Java 编程语言代理, 请参阅 java.lang.instrument
-splash:<imagepath> 使用指定的图像显示启动屏幕
有关详细信息, 请参阅 http://www.oracle.com/technetwork/java/javase/documentation/index.html。
通过-D设置系统属性参数
public class TestJVM {
public static void main(String[] args) {
String str = System.getProperty("str");
if (str == null) {
System.out.println("word");
} else {
System.out.println(str);
}
}
}
进行编译、测试:
javac TestJVM.java # 编译
java TestJVM #测试
word #输出结果
java ‐Dstr=123 TestJVM #-D设置系统属性参数
123 #输出结果
C:\Users\CYJ>java -version
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
-server与-client参数
可以通过-server或-client设置jvm的运行参数。
它们的区别是:
Server VM的初始堆空间会大一些,默认使用的是并行垃圾回收器,启动慢运行快。
Client VM相对来讲会保守一些,初始堆空间会小一些,使用串行的垃圾回收器,它的目标是为了让JVM的启动速度更快,但运行速度会比Serverm模式慢些。JVM在启动的时候会根据硬件和操作系统自动选择使用Server还是Client类型的JVM。
32位操作系统
如果是Windows系统,不论硬件配置如何,都默认使用Client类型的JVM。
如果是其他操作系统上,机器配置有2GB以上的内存同时有2个以上CPU的话默认使用server模式,否则使用client模式。
64位操作系统
只有server类型,不支持client类型。
1.2 -X参数 (非标准参数)
-Xint
-Xcomp
C:\Users\CYJ>java -X
-Xmixed 混合模式执行 (默认)
-Xint 仅解释模式执行
-Xbootclasspath: <用 ; 分隔的目录和 zip/jar 文件> 设置搜索路径以引导类和资源
-Xbootclasspath/a: <用 ; 分隔的目录和 zip/jar 文件> 附加在引导类路径末尾
-Xbootclasspath/p: <用 ; 分隔的目录和 zip/jar 文件> 置于引导类路径之前
-Xdiag 显示附加诊断消息
-Xnoclassgc 禁用类垃圾收集
-Xincgc 启用增量垃圾收集
-Xloggc:<file> 将 GC 状态记录在文件中 (带时间戳)
-Xbatch 禁用后台编译
-Xms<size> 设置初始 Java 堆大小
-Xmx<size> 设置最大 Java 堆大小
-Xss<size> 设置 Java 线程堆栈大小
-Xprof 输出 cpu 配置文件数据
-Xfuture 启用最严格的检查, 预期将来的默认值
-Xrs 减少 Java/VM 对操作系统信号的使用 (请参阅文档)
-Xcheck:jni 对 JNI 函数执行其他检查
-Xshare:off 不尝试使用共享类数据
-Xshare:auto 在可能的情况下使用共享类数据 (默认)
-Xshare:on 要求使用共享类数据, 否则将失败。
-XshowSettings 显示所有设置并继续
-XshowSettings:all
显示所有设置并继续
-XshowSettings:vm 显示所有与 vm 相关的设置并继续
-XshowSettings:properties 显示所有属性设置并继续
-XshowSettings:locale 显示所有与区域设置相关的设置并继续
-X 选项是非标准选项, 如有更改, 恕不另行通知。
-Xint、-Xcomp、-Xmixed
-Xint标记会强制JVM执行所有的字节码,当然这会降低运行速度,通常低10倍或更多。
-Xcomp参数与它(-Xint)正好相反,JVM在第一次使用时会把所有的字节码编译成本地代码,从而带来最大程度的优化
然而,很多应用在使用-Xcomp也会有一些性能损失,当然这比使用-Xint损失的少,原因是-xcomp没有让JVM启用JIT编 译器的全部功能。JIT编译器可以对是否需要编译做判断,如果所有代码都进行编译的话,对于一些只执行一次的代码就 没有意义了。
-Xmixed是混合模式,将解释模式与编译模式进行混合使用,由jvm自己决定,这是jvm默认的模式,也是推荐使用的模式。
1.3 -XX参数(使用率较高)
-XX:newSize
-XX:+UseSerialGC
-XX参数也是非标准参数,主要用于jvm的调优和debug操作。
-XX参数的使用有2种方式,一种是boolean类型,一种是非boolean类型:
boolean类型
格式:-XX:[+-]
如:-XX:+DisableExplicitGC 表示禁用手动调用gc操作,也就是说调用System.gc()无效
非boolean类型
格式:-XX:
如:-XX:NewRatio=1 表示新生代和老年代的比值
-Xms与-Xmx参数
-Xms与-Xmx分别是设置jvm的堆内存的初始大小和最大大小。
-Xmx2048m:等价于-XX:MaxHeapSize,设置JVM最大堆内存为2048M。
-Xms512m:等价于-XX:InitialHeapSize,设置JVM初始堆内存为512M。
适当的调整jvm的内存大小,可以充分利用服务器资源,让程序跑的更快。
查看jvm的运行参数
查看jvm的运行参数,这个需求可能会存在2种情况:
第一,运行java命令时打印出运行参数;需要添加-XX:+PrintFlagsFinal参数即可。
第二,查看正在运行的java进程的参数;jinfo命令查看。
查看所有的参数,用法:jinfo ‐flags <进程id>
通过jps 或者 jps ‐l 查看java进程
查看某一参数的值,用法:jinfo ‐flag <参数名> <进程id>
2.jvm的内存模型
2.1 jdk1.7的堆内存模型
Young 年轻区(代)
Young区被划分为三部分,Eden区和两个大小严格相同的Survivor区,其中,Survivor区间中,某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用,在Eden区间变满的时候, GC就会将存活的对象移到空闲的Survivor区间
中,根据JVM的策略,在经过几次垃圾收集后,任然存活于Survivor的对象将被移动到Tenured区间。
Tenured 年老区
Tenured区主要保存生命周期长的对象,一般是一些老的对象,当一些对象在Young复制转移一定的次数以后,对象就会被转移到Tenured区,一般如果系统中用了application级别的缓存,缓存中的对象往往会被转移到这一区间。
Perm 永久区
Perm代主要保存class,method,filed对象,这部份的空间一般不会溢出,除非一次性加载了很多的类,不过在涉及到热部署的应用服务器的时候,有时候会遇到java.lang.OutOfMemoryError : PermGen space 的错误,造成这个错误的很大原因
就有可能是每次都重新部署,但是重新部署后,类的class没有被卸载掉,这样就造成了大量的class对象保存在了perm中,这种情况下,一般重新启动应用服务器可以解决问题。
Virtual区:
最大内存和初始内存的差值,就是Virtual区。
2.2 jdk1.8的堆内存模型
由上图可以看出,jdk1.8的内存模型是由2部分组成,年轻代 + 年老代。
年轻代:Eden + 2*Survivor
年老代:OldGen
在jdk1.8中变化最大的Perm区,用Metaspace(元数据空间)进行了替换。需要特别说明的是:Metaspace所占用的内存空间不是在虚拟机内部,而是在本地内存空间中,这也是与1.7的永久代最大的区别所在。
2.3 为什么要废弃1.7中的永久区?
官网给出了解释:http://openjdk.java.net/jeps/122
This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.
移除永久代是为融合HotSpot JVM与 JRockit VM而做出的努力,因为JRockit没有永久代,不需要配置永久代。
现实使用中,由于永久代内存经常不够用或发生内存泄露,爆出异常java.lang.OutOfMemoryError: PermGen。基于此,将永久区废弃,而改用元空间,改为了使用本地内存空间。
2.4 通过jstat命令进行查看堆内存使用情况
jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:
jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]
查看class加载统计
C:\Users\CYJ>jps
11728 Bootstrap
14060 Jps
C:\Users\CYJ>jstat -class 11728
Loaded Bytes Unloaded Bytes Time
3189 6200.7 0 0.0 1.83
说明:
Loaded:加载class的数量
Bytes:所占用空间大小
Unloaded:未加载数量
Bytes:未加载占用空间
Time:时间
查看编译统计
C:\Users\CYJ>jstat -compiler 11728
Compiled Failed Invalid Time FailedType FailedMethod
1901 0 0 2.29 0
说明:
Compiled:编译数量。
Failed:失败数量
Invalid:不可用数量
Time:时间
FailedType:失败类型
FailedMethod:失败的方法
垃圾回收统计
C:\Users\CYJ>jstat -gc 11728
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
10752.0 10752.0 0.0 10730.1 65024.0 30674.4 173568.0 3967.0 17152.0 16607.2 2048.0 1891.7 1 0.011 0 0.000 0.011
#也可以指定打印的间隔和次数,每1秒中打印一次,共打印5次
C:\Users\CYJ>jstat -gc 11728 1000 5
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
10752.0 10752.0 0.0 10730.1 65024.0 30999.6 173568.0 3967.0 17152.0 16607.2 2048.0 1891.7 1 0.011 0 0.000 0.011
10752.0 10752.0 0.0 10730.1 65024.0 30999.6 173568.0 3967.0 17152.0 16607.2 2048.0 1891.7 1 0.011 0 0.000 0.011
10752.0 10752.0 0.0 10730.1 65024.0 30999.6 173568.0 3967.0 17152.0 16607.2 2048.0 1891.7 1 0.011 0 0.000 0.011
10752.0 10752.0 0.0 10730.1 65024.0 30999.6 173568.0 3967.0 17152.0 16607.2 2048.0 1891.7 1 0.011 0 0.000 0.011
10752.0 10752.0 0.0 10730.1 65024.0 30999.6 173568.0 3967.0 17152.0 16607.2 2048.0 1891.7 1 0.011 0 0.000 0.011
说明:
S0C:第一个Survivor区的大小(KB)
S1C:第二个Survivor区的大小(KB)
S0U:第一个Survivor区的使用大小(KB)
S1U:第二个Survivor区的使用大小(KB)
EC:Eden区的大小(KB)
EU:Eden区的使用大小(KB)
OC:Old区大小(KB)
OU:Old使用大小(KB)
MC:方法区大小(KB)
MU:方法区使用大小(KB)
CCSC:压缩类空间大小(KB)
CCSU:压缩类空间使用大小(KB)
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
3.jmap的使用以及内存溢出分析
前面通过jstat可以对jvm堆的内存进行统计分析,而jmap可以获取到更加详细的内容,如:内存使用情况的汇总、对内存溢出的定位与分析。
3.1 查看内存使用情况
C:\Users\CYJ>jmap -heap 11728
Attaching to process ID 11728, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.151-b12
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration: #堆内存配置信息
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 4259315712 (4062.0MB)
NewSize = 88604672 (84.5MB)
MaxNewSize = 1419771904 (1354.0MB)
OldSize = 177733632 (169.5MB)
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 = 66584576 (63.5MB)
used = 32076464 (30.590499877929688MB)
free = 34508112 (32.90950012207031MB)
48.17401555579478% used
From Space:
capacity = 11010048 (10.5MB)
used = 10987608 (10.478599548339844MB)
free = 22440 (0.02140045166015625MB)
99.79618617466518% used
To Space:
capacity = 11010048 (10.5MB)
used = 0 (0.0MB)
free = 11010048 (10.5MB)
0.0% used
PS Old Generation #年老代
capacity = 177733632 (169.5MB)
used = 4062192 (3.8740081787109375MB)
free = 173671440 (165.62599182128906MB)
2.2855505479120577% used
13795 interned Strings occupying 1879808 bytes.
3.2 查看内存中对象数量及大小
#查看所有对象,包括活跃以及非活跃的
jmap ‐histo <pid> | more
#查看活跃对象
jmap ‐histo:live <pid> | more
C:\Users\CYJ>jmap -histo:live 11728 | more
num #instances #bytes class name
----------------------------------------------
1: 35487 6423112 [C
2: 1969 1971024 [B
3: 34061 817464 java.lang.String
4: 5945 523160 java.lang.reflect.Method
5: 15932 509824 java.util.HashMap$Node
6: 3535 402416 java.lang.Class
7: 4154 243528 [Ljava.lang.Object;
8: 1863 201384 [I
9: 1252 190912 [Ljava.util.HashMap$Node;
10: 5934 189888 java.util.concurrent.ConcurrentHashMap$Node
11: 4368 92240 [Ljava.lang.Class;
12: 1858 89184 java.util.HashMap
13: 1288 82800 [Ljava.lang.String;
14: 95 82192 [Ljava.util.concurrent.ConcurrentHashMap$Node;
15: 5082 81312 java.lang.Object
16: 1893 75720 java.util.LinkedHashMap$Entry
17: 738 59040 java.lang.reflect.Constructor
18: 143 54256 [Ljava.util.WeakHashMap$Entry;
19: 736 52992 java.lang.reflect.Field
20: 399 50888 [Ljava.lang.reflect.Method;
21: 1496 47872 java.util.Hashtable$Entry
22: 1089 43560 java.lang.ref.SoftReference
23: 1086 43440 java.util.TreeMap$Entry
24: 841 40368 org.apache.tomcat.util.modeler.AttributeInfo
25: 987 39480 java.lang.ref.Finalizer
26: 133 33672 [[C
-- More --
#对象说明
B byte
C char
D double
F float
I int
J long
Z boolean
[ 数组,如[I表示int[]
[L+类名 其他对象
3.3 将内存使用情况dump到文件中
#用法:
jmap ‐dump:format=b,file=dumpFileName <pid>
#示例
jmap ‐dump:format=b,file=/tmp/dump.dat 11728
3.4 通过jhat对dump文件进行分析
#用法:
jhat ‐port <port> <file>
#示例:
jhat ‐port 9999 /tmp/dump.dat
3.5 通过MAT工具对dump文件进行分析
3.5.1 MAT工具介绍
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。
官网地址:https://www.eclipse.org/mat/
3.5.2 下载安装
下载地址:https://www.eclipse.org/mat/downloads.php
下载解压
3.5.3使用
无
4.内存溢出的定位与分析
内存溢出在实际的生产环境中经常会遇到,比如,不断的将数据写入到一个集合中,出现了死循环,读取超大的文件等等,都可能会造成内存溢出。如果出现了内存溢出,首先我们需要定位到发生内存溢出的环节,并且进行分析,是正常还是非正常情况,如果是正常的需求,就应该考虑加大内存的设置,如果是非正常需求,那么就要对代码进行修改,修复这个bug。首先,我们得先学会如何定位问题,然后再进行分析。如何定位问题呢,我们需要借助于jmap与MAT工具进行定位分析。
4.1模拟内存溢出
编写代码,向List集合中添加100万个字符串,每个字符串由1000个UUID组成。如果程序能够正常执行,最后打印ok。
/**
* @description:
* @author: 大佬味的小男孩
* @date: 2020-08-10 21:54
**/
public class TestJvmOutOfMemory {
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
for (int i = 0; i < 10000000; i++) {
String str = "";
for (int j = 0; j < 1000; j++) {
str += UUID.randomUUID().toString();
}
list.add(str);
}
System.out.println("ok");
}
}
为了演示效果,我们将设置执行的参数,这里使用的是Idea编辑器。
可以看到,当发生内存溢出时,会dump文件到java_pid17672.hprof。
4.2 导入到MAT工具中进行分析
可以看到,有88.03%的内存由Object[]数组占有,所以比较可疑。
分析:这个可疑是正确的,因为已经有超过90%的内存都被它占有,这是非常有可能出现内存溢出的
可以看到集合中存储了大量的uuid字符串。
5.jstack的使用
有些时候我们需要查看下jvm中的线程执行情况,比如,发现服务器的CPU的负载突然增高了、出现了死锁、死循环等,我们该如何分析呢?
由于程序是正常运行的,没有任何的输出,从日志方面也看不出什么问题,所以就需要看下jvm的内部线程的执行情况,然后再进行分析查找出原因。这个时候,就需要借助于jstack命令了,jstack的作用是将正在运行的jvm的线程情况进行快照,并且打印出来:
#用法:jstack <pid>
C:\Users\CYJ>jps
11568 org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar
18384
19424 Jps
14920 Launcher
2024 KotlinCompileDaemon
6920 Bootstrap
18188 RemoteMavenServer
C:\Users\CYJ>jstack 6920
2020-08-10 22:18:43
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode):
"ajp-nio-8009-AsyncTimeout" #46 daemon prio=5 os_prio=0 tid=0x000000001eb4f800 nid=0x374c waiting on condition [0x00000000223cf000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1133)
at java.lang.Thread.run(Thread.java:748)
"ajp-nio-8009-Acceptor-0" #45 daemon prio=5 os_prio=0 tid=0x000000001eb44000 nid=0x2754 runnable [0x00000000222cf000]
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 <0x000000076f7c9740> (a java.lang.Object)
at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:455)
at java.lang.Thread.run(Thread.java:748)
"ajp-nio-8009-ClientPoller-1" #44 daemon prio=5 os_prio=0 tid=0x000000001eb4b000 nid=0x21ac runnable [0x00000000221ce000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x000000076c2d6708> (a sun.nio.ch.Util$3)
- locked <0x000000076c2d66f8> (a java.util.Collections$UnmodifiableSet)
- locked <0x000000076c2d65a8> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:796)
at java.lang.Thread.run(Thread.java:748)
"ajp-nio-8009-ClientPoller-0" #43 daemon prio=5 os_prio=0 tid=0x000000001eb42800 nid=0x4ac0 runnable [0x00000000220cf000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x000000076c2d2580> (a sun.nio.ch.Util$3)
- locked <0x000000076c2d2570> (a java.util.Collections$UnmodifiableSet)
- locked <0x000000076c2d2420> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:796)
at java.lang.Thread.run(Thread.java:748)
"ajp-nio-8009-exec-10" #42 daemon prio=5 os_prio=0 tid=0x000000001eb49800 nid=0x3bb8 waiting on condition [0x0000000021fce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c2cf900> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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)
"ajp-nio-8009-exec-9" #41 daemon prio=5 os_prio=0 tid=0x000000001eb42000 nid=0x4780 waiting on condition [0x0000000021ecf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c2cf900> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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)
"ajp-nio-8009-exec-8" #40 daemon prio=5 os_prio=0 tid=0x000000001eb48800 nid=0x3588 waiting on condition [0x0000000021dce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c2cf900> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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)
"ajp-nio-8009-exec-7" #39 daemon prio=5 os_prio=0 tid=0x000000001eb41000 nid=0x4050 waiting on condition [0x0000000021ccf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c2cf900> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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)
"ajp-nio-8009-exec-6" #38 daemon prio=5 os_prio=0 tid=0x000000001eb47000 nid=0x38e8 waiting on condition [0x0000000021bce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c2cf900> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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)
"ajp-nio-8009-exec-5" #37 daemon prio=5 os_prio=0 tid=0x000000001eb43800 nid=0x174 waiting on condition [0x0000000021ace000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c2cf900> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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)
"ajp-nio-8009-exec-4" #36 daemon prio=5 os_prio=0 tid=0x000000001eb46800 nid=0x44c4 waiting on condition [0x00000000219cf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c2cf900> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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)
"ajp-nio-8009-exec-3" #35 daemon prio=5 os_prio=0 tid=0x000000001eb45800 nid=0x472c waiting on condition [0x00000000218ce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c2cf900> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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)
"ajp-nio-8009-exec-2" #34 daemon prio=5 os_prio=0 tid=0x000000001eb45000 nid=0x3c48 waiting on condition [0x00000000217ce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c2cf900> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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)
"ajp-nio-8009-exec-1" #33 daemon prio=5 os_prio=0 tid=0x000000001eb48000 nid=0x5f4 waiting on condition [0x00000000216ce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c2cf900> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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-AsyncTimeout" #32 daemon prio=5 os_prio=0 tid=0x000000001ea5e000 nid=0x1128 waiting on condition [0x00000000215cf000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1133)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-Acceptor-0" #31 daemon prio=5 os_prio=0 tid=0x000000001ea5d800 nid=0x1620 runnable [0x00000000214cf000]
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 <0x000000076f7c8408> (a java.lang.Object)
at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:455)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-ClientPoller-1" #30 daemon prio=5 os_prio=0 tid=0x000000001ea5c000 nid=0xea8 runnable [0x00000000213cf000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x000000076c2c3898> (a sun.nio.ch.Util$3)
- locked <0x000000076c2c3888> (a java.util.Collections$UnmodifiableSet)
- locked <0x000000076c2c3738> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:796)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-ClientPoller-0" #29 daemon prio=5 os_prio=0 tid=0x000000001ea60800 nid=0x4aec runnable [0x00000000212cf000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x000000076c2bf6a0> (a sun.nio.ch.Util$3)
- locked <0x000000076c2bf690> (a java.util.Collections$UnmodifiableSet)
- locked <0x000000076c2bf540> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:796)
at java.lang.Thread.run(Thread.java:748)
"http-nio-8080-exec-10" #28 daemon prio=5 os_prio=0 tid=0x000000001ea5f000 nid=0x1e00 waiting on condition [0x00000000211ce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c24f638> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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=0 tid=0x000000001ea59800 nid=0x1cec waiting on condition [0x00000000210ce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c24f638> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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=0 tid=0x000000001ea5c800 nid=0x8b4 waiting on condition [0x0000000020fce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c24f638> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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=0 tid=0x000000001ea5b000 nid=0x2f88 waiting on condition [0x0000000020ece000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c24f638> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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=0 tid=0x000000001ea5f800 nid=0x2798 waiting on condition [0x0000000020dce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c24f638> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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=0 tid=0x000000001ea5a800 nid=0x2ec8 waiting on condition [0x0000000020ccf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c24f638> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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=0 tid=0x000000001eaa4000 nid=0x4190 waiting on condition [0x0000000020bcf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c24f638> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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=0 tid=0x000000001edc6800 nid=0x414c waiting on condition [0x0000000020ace000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c24f638> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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=0 tid=0x000000001edc5800 nid=0x4b98 waiting on condition [0x00000000209ce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c24f638> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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=0 tid=0x000000001edc5000 nid=0x4064 waiting on condition [0x00000000208ce000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c24f638> (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:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
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)
"ContainerBackgroundProcessor[StandardEngine[Catalina]]" #18 daemon prio=5 os_prio=0 tid=0x000000001edc0800 nid=0x4bcc waiting on condition [0x00000000207cf000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1357)
at java.lang.Thread.run(Thread.java:748)
"NioBlockingSelector.BlockPoller-2" #15 daemon prio=5 os_prio=0 tid=0x000000001e683000 nid=0x215c runnable [0x000000002001f000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x000000076f593270> (a sun.nio.ch.Util$3)
- locked <0x000000076f593280> (a java.util.Collections$UnmodifiableSet)
- locked <0x000000076f5931f0> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:298)
"NioBlockingSelector.BlockPoller-1" #14 daemon prio=5 os_prio=0 tid=0x000000001e682000 nid=0x3530 runnable [0x000000001ff1f000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x000000076f59b270> (a sun.nio.ch.Util$3)
- locked <0x000000076f59b280> (a java.util.Collections$UnmodifiableSet)
- locked <0x000000076f59b1f0> (a sun.nio.ch.WindowsSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:298)
"GC Daemon" #13 daemon prio=2 os_prio=-2 tid=0x000000001e2db800 nid=0x3034 in Object.wait() [0x000000001fc1e000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076f593408> (a sun.misc.GC$LatencyLock)
at sun.misc.GC$Daemon.run(GC.java:117)
- locked <0x000000076f593408> (a sun.misc.GC$LatencyLock)
"AsyncFileHandlerWriter-789451787" #12 daemon prio=5 os_prio=0 tid=0x000000001d592800 nid=0x1a68 waiting on condition [0x000000001e04f000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076f593598> (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.LinkedBlockingDeque.pollFirst(LinkedBlockingDeque.java:522)
at java.util.concurrent.LinkedBlockingDeque.poll(LinkedBlockingDeque.java:684)
at org.apache.juli.AsyncFileHandler$LoggerThread.run(AsyncFileHandler.java:160)
"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000001bffe800 nid=0x2640 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x000000001bfcb800 nid=0x2bf0 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x000000001bfc7000 nid=0x3ce0 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000000001d492800 nid=0x8c8 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001bfb2800 nid=0x2e04 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001bfb1800 nid=0x3070 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001bf8f000 nid=0x1ae4 in Object.wait() [0x000000001d2ee000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076f5d88d0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x000000076f5d88d0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000002a15800 nid=0x332c in Object.wait() [0x000000001d1ee000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076f5d8b00> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x000000076f5d8b00> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"main" #1 prio=5 os_prio=0 tid=0x0000000002922800 nid=0x35a8 runnable [0x00000000025ae000]
java.lang.Thread.State: RUNNABLE
at java.net.DualStackPlainSocketImpl.accept0(Native Method)
at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
- locked <0x000000076c2dc850> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
at org.apache.catalina.core.StandardServer.await(StandardServer.java:466)
at org.apache.catalina.startup.Catalina.await(Catalina.java:769)
at org.apache.catalina.startup.Catalina.start(Catalina.java:715)
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 org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:353)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:493)
"VM Thread" os_prio=2 tid=0x000000001bf67800 nid=0x4218 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002937000 nid=0x4b8c runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002938800 nid=0x4548 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x000000000293b000 nid=0x3290 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000000000293c800 nid=0x1714 runnable
"VM Periodic Task Thread" os_prio=2 tid=0x000000001d533000 nid=0x3060 waiting on condition
JNI global references: 243
5.1 线程的状态
在Java中线程的状态一共被分成6种:
初始态(NEW)
创建一个Thread对象,但还未调用start()启动线程时,线程处于初始态。
运行态(RUNNABLE),在Java中,运行态包括 就绪态 和 运行态。
就绪态
该状态下的线程已经获得执行所需的所有资源,只要CPU分配执行权就能运行。
所有就绪态的线程存放在就绪队列中。
运行态
获得CPU执行权,正在执行的线程。
由于一个CPU同一时刻只能执行一条线程,因此每个CPU每个时刻只有一条运行态的线程。
阻塞态(BLOCKED)
当一条正在执行的线程请求某一资源失败时,就会进入阻塞态。
而在Java中,阻塞态专指请求锁失败时进入的状态。
由一个阻塞队列存放所有阻塞态的线程。
处于阻塞态的线程会不断请求资源,一旦请求成功,就会进入就绪队列,等待执行。
等待态(WAITING)
当前线程中调用wait、join、park函数时,当前线程就会进入等待态。
也有一个等待队列存放所有等待态的线程。
线程处于等待态表示它需要等待其他线程的指示才能继续运行。
进入等待态的线程会释放CPU执行权,并释放资源(如:锁)
超时等待态(TIMED_WAITING)
当运行中的线程调用sleep(time)、wait、join、parkNanos、parkUntil时,就会进入该状态;
它和等待态一样,并不是因为请求不到资源,而是主动进入,并且进入后需要其他线程唤醒;
进入该状态后释放CPU执行权 和 占有的资源。
与等待态的区别:到了超时时间后自动进入阻塞队列,开始竞争锁。
终止态(TERMINATED)
线程执行结束后的状态。
5.2 死锁问题
如果在生产环境发生了死锁,我们将看到的是部署的程序没有任何反应了,这个时候我们可以借助jstack进行分析,下面我们实战下查找死锁的原因。
5.2.1 构造死锁
编写代码,启动2个线程,Thread1拿到了obj1锁,准备去拿obj2锁时,obj2已经被Thread2锁定,所以发生死锁。
/**
* @description:
* @author: 大佬味的小男孩
* @date: 2020-08-10 22:32
**/
public class TestDeadLock {
private static Object obj1 = new Object();
private static Object obj2 = new Object();
private static class Thread1 implements Runnable {
@Override
public void run() {
synchronized (obj1) {
System.out.println("Thread1 拿到了 obj1 的锁!");
try {
// 停顿2秒的意义在于,让Thread2线程拿到obj2的锁
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj2) {
System.out.println("Thread1 拿到了 obj2 的锁!");
}
}
}
}
private static class Thread2 implements Runnable {
@Override
public void run() {
synchronized (obj2) {
System.out.println("Thread2 拿到了 obj2 的锁!");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj1) {
System.out.println("Thread2 拿到了 obj1 的锁!");
}
}
}
}
public static void main(String[] args) {
new Thread(new Thread1()).start();
new Thread(new Thread2()).start();
}
}
5.2.2 使用jstack进行分析
C:\Users\CYJ>jps
18384
13368 Jps
16552 TestDeadLock
2024 KotlinCompileDaemon
13308 Launcher
18188 RemoteMavenServer
C:\Users\CYJ>jstack 16552
2020-08-10 22:37:30
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode):
"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x00000000016de000 nid=0xd9c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Thread-1" #12 prio=5 os_prio=0 tid=0x000000001e017800 nid=0x20d0 waiting for monitor entry [0x000000001ecdf000]
java.lang.Thread.State: BLOCKED (on object monitor)
at cn.TestDeadLock$Thread2.run(TestDeadLock.java:41)
- waiting to lock <0x000000076b7870c8> (a java.lang.Object)
- locked <0x000000076b7870d8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
"Thread-0" #11 prio=5 os_prio=0 tid=0x000000001e012800 nid=0x2b50 waiting for monitor entry [0x000000001ebdf000]
java.lang.Thread.State: BLOCKED (on object monitor)
at cn.TestDeadLock$Thread1.run(TestDeadLock.java:24)
- waiting to lock <0x000000076b7870d8> (a java.lang.Object)
- locked <0x000000076b7870c8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x000000001df9e800 nid=0x1d88 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000001df99000 nid=0x2b34 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000001df37000 nid=0x21fc waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x000000001df33000 nid=0x20e8 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x000000001df22800 nid=0x4b74 runnable [0x000000001e5de000]
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 <0x000000076b8c99e0> (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 <0x000000076b8c99e0> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001cb2f000 nid=0x4270 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001cb2e000 nid=0xd18 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000003547800 nid=0x1d04 in Object.wait() [0x000000001de7f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b608ec8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x000000076b608ec8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000003542000 nid=0x3730 in Object.wait() [0x000000001dd7f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b606b68> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x000000076b606b68> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=2 tid=0x000000001cae7800 nid=0x2214 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000003468000 nid=0x35a0 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000003469800 nid=0x3dcc runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x000000000346b000 nid=0x2204 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000000000346c800 nid=0x2864 runnable
"VM Periodic Task Thread" os_prio=2 tid=0x000000001e00d800 nid=0x3484 waiting on condition
JNI global references: 33
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x000000001cb0d7e8 (object 0x000000076b7870c8, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x000000001cb101d8 (object 0x000000076b7870d8, a java.lang.Object),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at cn.TestDeadLock$Thread2.run(TestDeadLock.java:41)
- waiting to lock <0x000000076b7870c8> (a java.lang.Object)
- locked <0x000000076b7870d8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
"Thread-0":
at cn.TestDeadLock$Thread1.run(TestDeadLock.java:24)
- waiting to lock <0x000000076b7870d8> (a java.lang.Object)
- locked <0x000000076b7870c8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
在输出的信息中,已经看到,发现了1个死锁,关键看这个。
"Thread-1":
at cn.TestDeadLock$Thread2.run(TestDeadLock.java:41)
- waiting to lock <0x000000076b7870c8> (a java.lang.Object)
- locked <0x000000076b7870d8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
"Thread-0":
at cn.TestDeadLock$Thread1.run(TestDeadLock.java:24)
- waiting to lock <0x000000076b7870d8> (a java.lang.Object)
- locked <0x000000076b7870c8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
可以清晰的看到:
Thread2获取了 <0x000000076b7870d8> 的锁,等待获取 <0x000000076b7870c8>这个锁
Thread1获取了 <0x000000076b7870c8> 的锁,等待获取 <0x000000076b7870d8>这个锁
由此可见,发生了死锁。
6.VisualVM工具的使用
VisualVM,能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的对象,反向查看分配的堆栈(如100个String对象分别由哪几个对象分配出来的)。
VisualVM使用简单,几乎0配置,功能还是比较丰富的,几乎囊括了其它JDK自带命令的所有功能。
内存信息
线程信息
Dump堆(本地进程)
Dump线程(本地进程)
打开堆Dump。堆Dump可以用jmap来生成。
打开线程Dump
生成应用快照(包含内存信息、线程信息等等)
性能分析。CPU分析(各个方法调用时间,检查哪些方法耗时多),内存分析(各类对象占用的内存,检查哪些类占用内存多)
6.1 启动
在jdk的安装目录的bin目录下,找到jvisualvm.exe,双击打开即可。
6.2 查看本地进程
无
6.3 查看CPU、内存、类、线程运行信息
6.4 查看线程详情
也可以点击右上角Dump按钮,将线程的信息导出,其实就是执行的jstack命令。
6.5 抽样器
6.6 监控远程的jvm
VisualJVM不仅是可以监控本地jvm进程,还可以监控远程的jvm进程,需要借助于JMX技术实现。
6.6.1 什么是JMX?
JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用。
6.6.2 监控远程的tomcat
想要监控远程的tomcat,就需要在远程的tomcat进行对JMX配置,方法如下:
#在tomcat的bin目录下,修改catalina.sh,添加如下的参数
JAVA_OPTS="‐Dcom.sun.management.jmxremote ‐
Dcom.sun.management.jmxremote.port=9999 ‐
Dcom.sun.management.jmxremote.authenticate=false ‐
Dcom.sun.management.jmxremote.ssl=false"
#这几个参数的意思是:
#‐Dcom.sun.management.jmxremote :允许使用JMX远程管理
#‐Dcom.sun.management.jmxremote.port=9999 :JMX远程连接端口
#‐Dcom.sun.management.jmxremote.authenticate=false :不进行身份认证,任何用户都可以连接
#‐Dcom.sun.management.jmxremote.ssl=false :不使用ssl
6.6.3 使用VisualJVM连接远程tomcat
无