1 jps: jps命令可以方便的查看进程id,启动类,传入参数, jvm参数
jps命令类似于linux 下的ps,但是只列出java的进程. 直接运行jps不加参数,会列出java程序的进场ID,及main函数名称
C:\Users\shj>jps
42340 Jps
41064
42040 JucApplication
37804 Launcher
可以看到,目前有4个java进程
-q 可以让jps只查看进程ID
C:\Users\shj>jps -q
25972
41064
42040
37804
-m 可以输出传递给java进场(main方法) 的参数
C:\Users\shj>jps -m
40884 Jps -m
41064
42040 JucApplication
37804 Launcher D:/IDEA2020/lib/plexus-interpolation-1.25.jar;D:/IDEA2020/lib/netty-resolver-4.1.52.Final.jar;D:/IDEA2020/lib/lz4-java-1.7.1.jar;D:/IDEA2020/lib/plexus-component-annotations-1.7.1.jar;D:/IDEA2020/lib/platform-api.jar;D:/IDEA2020/lib/forms_rt.jar;D:/IDEA2020/lib/netty-codec-4.1.52.Final.jar;D:/IDEA2020/lib/oro-2.0.8.jar;D:/IDEA2020/lib/netty-buffer-4.1.52.Final.jar;D:/IDEA2020/lib/netty-transport-4.1.52.Final.jar;D:/IDEA2020/lib/protobuf-java-3.13.0.jar;D:/IDEA2020/lib/maven-repository-metadata-3.6.1.jar;D:/IDEA2020/lib/idea_rt.jar;D:/IDEA2020/plugins/java/lib/maven-resolver-transport-http-1.3.3.jar;D:/IDEA2020/lib/commons-lang3-3.10.jar;D:/IDEA2020/lib/trove4j.jar;D:/IDEA2020/plugins/java/lib/jps-javac-extension-1.jar;D:/IDEA2020/lib/plexus-utils-3.2.0.jar;D:/IDEA2020/lib/util.jar;D:/IDEA2020/lib/nanoxml-2.2.3.jar;D:/IDEA2020/lib/maven-resolver-api-1.3.3.jar;D:/IDEA2020/lib/log4j.jar;D:/IDEA2020/plugins/java/lib/javac2.jar;D:/IDEA2020/lib/intellij-deps-fastutil-8.4.1-4.jar;D
-l 用于输出main函数的完整路径
C:\Users\shj>jps -m -l
19080 sun.tools.jps.Jps -m -l
41064
42040 com.example.juc.JucApplication
37804 org.jetbrains.jps.cmdline.Launcher D:/IDEA2020/lib/plexus-interpolation-1.25.jar;D:/IDEA2020/lib/netty-resolver-4.1.52.Final.jar;D:/IDEA2020/lib/lz4-java-1.7.1.jar;D:/IDEA2020/lib/plexus-component-annotations-1.7.1.jar;D:/IDEA2020/lib/platform-api.jar;D:/IDEA2020/lib/forms_rt.jar;D:/IDEA2020/lib/netty-codec-4.1.52.Final.jar;D:/IDEA2020/lib/oro-2.0.8.jar;D:/IDEA2020/lib/netty-buffer-4.1.52.Final.jar;D:/IDEA2020/lib/netty-transport-4.1.52.Final.jar;D:/IDEA2020/lib/protobuf-java-3.13.0.jar;D:/IDEA2020/lib/maven-repository-metadata-3.6.1.jar;D:/IDEA2020/lib/idea_rt.jar;D:/IDEA2020/plugins/java/lib/maven-resolver-transport-http-1.3.3.jar;D:/IDEA2020/lib/commons-lang3-3.10.jar;D:/IDEA2020/lib/trove4j.jar;D:/IDEA2020/plugins/java/lib/jps-javac-extension-1.jar;D:/IDEA2020/lib/plexus-utils-3.2.0.jar;D:/IDEA2020/lib/util.jar;D:/IDEA2020/lib/nanoxml-2.2.3.jar;D:/IDEA2020/lib/maven-resolver-api-1.3.3.jar;D:/IDEA2020/lib/log4j.jar;D:/IDEA2020/plugins/java/lib/javac2.jar;D:/IDEA2020/lib/intellij-deps-fastutil-8.4.1-4.jar;D
-v 可以查看传递给jvm的参数
C:\Users\shj>jps -m -l -v
37272 sun.tools.jps.Jps -m -l -v -Denv.class.path=.;C:\Program Files\Java\jdk1.8.0_281\lib\dt.jar;C:\Program Files\Java\jdk1.8.0_281\lib\tools.jar; -Dapplication.home=C:\Program Files\Java\jdk1.8.0_281 -Xms8m
41064 exit -Xms128m -Xmx2020m -XX:ReservedCodeCacheSize=512m -XX:+UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=50 -XX:CICompilerCount=2 -XX:+HeapDumpOnOutOfMemoryError -XX:-OmitStackTraceInFastThrow -ea -Dsun.io.useCanonCaches=false -Djdk.http.auth.tunneling.disabledSchemes="" -Djdk.attach.allowAttachSelf=true -Djdk.module.illegalAccess.silent=true -Dkotlinx.coroutines.debug=off -javaagent:C:\Users\Public\.jetbrains\jetbrains-agent-v3.2.1.c46b.ed7=by https://zhile.io -Djb.vmOptionsFile=C:\Users\shj\AppData\Roaming\JetBrains\IntelliJIdea2020.3\idea64.exe.vmoptions -Djava.library.path=D:\IDEA2020\jbr\\bin;D:\IDEA2020\jbr\\bin\server -Didea.jre.check=true -Dide.native.launcher=true -Didea.vendor.name=JetBrains -Didea.paths.selector=IntelliJIdea2020.3 -XX:ErrorFile=C:\Users\shj\java_error_in_idea64_%p.log -XX:HeapDumpPath=C:\Users\shj\java_error_in_idea64.hprof
42040 com.example.juc.JucApplication -XX:TieredStopAtLevel=1 -Xverify:none -Dspring.output.ansi.enabled=always -javaagent:D:\IDEA2020\lib\idea_rt.jar=63835:D:\IDEA2020\bin -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dfile.encoding=UTF-8
37804 org.jetbrains.jps.cmdline.Launcher D:/IDEA2020/lib/plexus-interpolation-1.25.jar;D:/IDEA2020/lib/netty-resolver-4.1.52.Final.jar;D:/IDEA2020/lib/lz4-java-1.7.1.jar;D:/IDEA2020/lib/plexus-component-annotations-1.7.1.jar;D:/IDEA2020/lib/platform-api.jar;D:/IDEA2020/lib/forms_rt.jar;D:/IDEA2020/lib/netty-codec-4.1.52.Final.jar;D:/IDEA2020/lib/oro-2.0.8.jar;D:/IDEA2020/lib/netty-buffer-4.1.52.Final.jar;D:/IDEA2020/lib/netty-transport-4.1.52.Final.jar;D:/IDEA2020/lib/protobuf-java-3.13.0.jar;D:/IDEA2020/lib/maven-repository-metadata-3.6.1.jar;D:/IDEA2020/lib/idea_rt.jar;D:/IDEA2020/plugins/java/lib/maven-resolver-transport-http-1.3.3.jar;D:/IDEA2020/lib/commons-lang3-3.10.jar;D:/IDEA2020/lib/trove4j.jar;D:/IDEA2020/plugins/java/lib/jps-javac-extension-1.jar;D:/IDEA2020/lib/plexus-utils-3.2.0.jar;D:/IDEA2020/lib/util.jar;D:/IDEA2020/lib/nanoxml-2.2.3.jar;D:/IDEA2020/lib/maven-resolver-api-1.3.3.jar;D:/IDEA2020/lib/log4j.jar;D:/IDEA2020/plugins/java/lib/javac2.jar;D:/IDEA2020/lib/intellij-deps-fastutil-8.4.1-4.jar;D -Xmx700m -Djava.awt.headless=true -Djava.endorsed.dirs="" -Djdt.compiler.useSingleThread=true -Dpreload.project.path=D:/work/juc -Dpreload.config.path=C:/Users/shj/AppData/Roaming/JetBrains/IntelliJIdea2020.3/options -Dcompile.parallel=false -Drebuild.on.dependency.change=true -Dio.netty.initialSeedUniquifier=-8542068102786334792 -Dfile.encoding=GBK -Duser.language=zh -Duser.country=CN -Didea.paths.selector=IntelliJIdea2020.3 -Didea.home.path=D:\IDEA2020 -Didea.config.path=C:\Users\shj\AppData\Roaming\JetBrains\IntelliJIdea2020.3 -Didea.plugins.path=C:\Users\shj\AppData\Roaming\JetBrains\IntelliJIdea2020.3\plugins -Djps.log.dir=C:/Users/shj/AppData/Local/JetBrains/IntelliJIdea2020.3/log/build-log -Djps.fallback.jdk.home=D:/IDEA2020/jbr -Djps.fallback.jdk.version=11.0.10 -Dio.netty.noUnsafe=true -Djava.io.tmpdir=C:/Users/shj/AppData/Local/JetBrains/IntelliJIdea2020.3/compile-server/juc_a204acdc/_temp_ -Djps.backward.ref.index.builder=true -Dkotlin.incremental.compilation=true -Dkotlin.incremental.compilation.j
jps命令可以方便的查看进程id,启动类,传入参数, jvm参数,
2 jstat : jstat 可以非常详细的查看堆使用情况和GC情况
jstat 是一个可以用于观察java应用长须运行时信息的工具, 功能非常强大,可以查看堆信息的详细情况; 基本语法为
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
option 可选值查看
C:\Users\shj>jstat -options
-class 类加载器统计
-compiler 编译统计
-gc 垃圾回收统计
-gccapacity 堆内存统计
-gccause 近一次GC统计和原因
-gcmetacapacity 元数据空间统计
-gcnew 新生代垃圾回收统计
-gcnewcapacity 新生代内存统计
-gcold 老年代垃圾回收统计
-gcoldcapacity 老年代内存统计
-gcutil 垃圾回收统计(百分比)
-printcompilation 显示Java HotSpot VM编译方法统计
官方解释信息 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html#BEHIGDGJ
-t 表示在现实是加上Timestamp列, 从jvm启动开始计时
-h 表示周期性输出时,间隔多少行后输出表头
interval 用来指定统计周期,单位为毫秒
count 用来指定一共输出多少次数据
查看42020进程的类加载信息, 每秒统计一次,一共输出3次
C:\Users\shj>jstat -class 42040 1000 3
Loaded Bytes Unloaded Bytes Time
6075 10990.9 0 0.0 1.36
6075 10990.9 0 0.0 1.36
6075 10990.9 0 0.0 1.36
Loaded :表示载入类的数量
Bytes : 载入类的合计大小
Unloaded: 卸载类的数量
Bytes 卸载类的合计大小
Time 在加载和卸载类上花费的时间
C:\Users\shj>jstat -compiler 42040
Compiled Failed Invalid Time FailedType FailedMethod
2952 0 0 0.50 0
Compiled 表示变异任务执行的次数
Failed 表示编译失败的次数
Invalid 表示编译不可用的次数
Time 表示编译的总耗时
FailedType 表示最后一次编译失败的类型
FailedMethod 表示最后一次编译失败的类名和方法名
C:\Users\shj>jstat -gc 42040
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
11264.0 10752.0 0.0 8673.1 127488.0 82676.1 96256.0 6376.6 32128.0 29679.4 4480.0 3998.8 5 0.033 1 0.018 0.051
S0C (Current survivor space 0 capacity (kB).)年轻代第1个幸存区大小(KB)
S1C (Current survivor space 1 capacity (kB).) 年轻代第2个幸存区大小(KB)
S0U(Survivor space 0 utilization (kB).) 年轻代第1个幸存区已使用空间(KB)
S1U (Survivor space 1 utilization (kB).)年轻代第2个幸存区已使用空间(KB)
EC(Current eden space capacity (kB).) Eden(伊甸园)的容量 (字节)
EU(Eden space utilization (kB).) Eden(伊甸园)的已使用容量 (字节)
OC(Current old space capacity (kB).) 老年代大小
OU(Old space utilization (kB).) 老年代已使用容量
MC (Metaspace capacity (kB).)元空间大小
MU (Metacspace utilization (kB).) 元空间已使用容量
CCSC ( Compressed class space capacity (kB).)压缩类空间容量
CCSU (Compressed class space used (kB).)压缩类空间已使用容量
YGC(Number of young generation garbage collection events.) 年轻代垃圾回收的次数
YGCT(Young generation garbage collection time.) 年轻代垃圾回收持续时间
FGC ( Number of full GC events.) full GC的次数
FGCT(Full garbage collection time.) full gc的持续时间
GCT(Total garbage collection time.) 从jvm启动到现在,执行gc的总时间
C:\Users\shj>jstat -gccapacity 42040
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
86528.0 1379328.0 181248.0 11264.0 10752.0 127488.0 173568.0 2759680.0 96256.0 96256.0 0.0 1077248.0 32128.0 0.0 1048576.0 4480.0 5 1
NGCMN: Minimum new generation capacity (kB).
NGCMX: Maximum new generation capacity (kB).
NGC: Current new generation capacity (kB).
S0C: Current survivor space 0 capacity (kB).
S1C: Current survivor space 1 capacity (kB).
EC: Current eden space capacity (kB).
OGCMN: Minimum old generation capacity (kB).
OGCMX: Maximum old generation capacity (kB).
OGC: Current old generation capacity (kB).
OC: Current old space capacity (kB).
MCMN: Minimum metaspace capacity (kB).
MCMX: Maximum metaspace capacity (kB).
MC: Metaspace capacity (kB).
CCSMN: Compressed class space minimum capacity (kB).
CCSMX: Compressed class space maximum capacity (kB).
CCSC: Compressed class space capacity (kB).
YGC: Number of young generation GC events.
FGC: Number of full GC events.
C:\Users\shj>jstat -gccause 42040
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
0.00 80.66 98.46 6.62 92.38 89.26 5 0.033 1 0.018 0.051 Allocation Failure No GC
LGCC: Cause of last garbage collection 上次GC原因
GCC: Cause of current garbage collection 当前次GC原因
C:\Users\shj>jstat -gcnew 42040
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
11264.0 11264.0 6144.0 0.0 7 15 11264.0 158720.0 12293.7 6 0.044
TT: Tenuring threshold. 新生代晋升到老年代的年龄
MTT: Maximum tenuring threshold. 新生代晋升到老年代的年龄最大值
DSS: Desired survivor size (kB). 所需survivor大小
C:\Users\shj>jstat -gcutil 42040
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
54.55 0.00 12.57 6.63 92.38 89.26 6 0.044 1 0.018 0.062
S0: Survivor space 0 utilization as a percentage of the space's current capacity. s0区使用百分比
S1: Survivor space 1 utilization as a percentage of the space's current capacity.s1区使用百分比
E: Eden space utilization as a percentage of the space's current capacity. Eden 区使用百分比
O: Old space utilization as a percentage of the space's current capacity.old区使用百分比
M: Metaspace utilization as a percentage of the space's current capacity.Metaspace 区使用百分比
CCS: Compressed class space utilization as a percentage.
YGC: Number of young generation GC events.
YGCT: Young generation garbage collection time.
FGC: Number of full GC events.
FGCT: Full garbage collection time.
GCT: Total garbage collection time.
jstat 可以非常详细的查看堆使用情况和GC情况
3 jinfo: jinfo可以查看某个jvm参数运行时的实际值,也可修改部分值
jinfo 用来查看正在运行的java程序的扩展参数, 支持在运行时修改部分参数
语法:
jinfo [ option ] pid
jinfo [ option ] executable core
jinfo [ option ] [ servier-id ] remote-hostname-or-IP
C:\Users\shj>jinfo
Usage:
jinfo [option] <pid>
(to connect to running process)
jinfo [option] <executable <core>
(to connect to a core file)
jinfo [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)
where <option> is one of:
-flag <name> to print the value of the named VM flag
-flag [+|-]<name> to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
-flags to print VM flags
-sysprops to print Java system properties
<no option> to print both of the above
-h | -help to print this help message
很多情况下,java程序执行时不会指定所有参数,如果想知道某个jvm参数的默认值,查询文档肯呢个不会很方便,使用jinfo可以快速查看
C:\Users\shj>jinfo -flags 42040
Attaching to process ID 42040, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.281-b09
Non-default VM flags: -XX:-BytecodeVerificationLocal -XX:-BytecodeVerificationRemote -XX:CICompilerCount=4 -XX:InitialHeapSize=266338304 -XX:+ManagementServer -XX:MaxHeapSize=4238344192 -XX:MaxNewSize=1412431872 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=88604672 -XX:OldSize=177733632 -XX:TieredStopAtLevel=1 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line: -XX:TieredStopAtLevel=1 -Xverify:none -Dspring.output.ansi.enabled=always -javaagent:D:\IDEA2020\lib\idea_rt.jar=63835:D:\IDEA2020\bin -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dfile.encoding=UTF-8
jinfo不仅可以查看运行时某一个Java虚拟机参数的实际取值, 甚至可以在运行时修改部分参 数,并使之立即生效。 但是,并非所有参数都支持动态修改。参数只有被标记 manageable的flag可以被实时修改。其实,这个修改能力是 极其有限的
以下是查看进程中可以修改并立即生效的参数
linux命令: java -XX:+PrintFlagsFinal -version | grep manageable
:
window下使用 java -XX:+PrintFlagsFinal -version | findstr manageable
:
C:\Users\shj>java -XX:+PrintFlagsFinal -version | findstr manageable
intx CMSAbortablePrecleanWaitMillis = 100 {manageable}
intx CMSTriggerInterval = -1 {manageable}
intx CMSWaitDuration = 2000 {manageable}
bool HeapDumpAfterFullGC = false {manageable}
bool HeapDumpBeforeFullGC = false {manageable}
bool HeapDumpOnOutOfMemoryError = false {manageable}
ccstr HeapDumpPath = {manageable}
uintx MaxHeapFreeRatio = 100 {manageable}
uintx MinHeapFreeRatio = 0 {manageable}
bool PrintClassHistogram = false {manageable}
bool PrintClassHistogramAfterFullGC = false {manageable}
bool PrintClassHistogramBeforeFullGC = false {manageable}
bool PrintConcurrentLocks = false {manageable}
bool PrintGC = false {manageable}
bool PrintGCDateStamps = false {manageable}
bool PrintGCDetails = false {manageable}
bool PrintGCID = false {manageable}
bool PrintGCTimeStamps = false {manageable}
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
修改方式:
布尔类型: jinfo -flag +-参数 pid
非布尔类型: jinfo -flag 参数名=参数值 pid
C:\Users\shj>jinfo -flag PrintGCDetails 42040
-XX:-PrintGCDetails
C:\Users\shj>jinfo -flag +PrintGCDetails 42040
C:\Users\shj>jinfo -flag PrintGCDetails 42040
-XX:+PrintGCDetails
jinfo可以查看某个jvm参数运行时的实际值,也可修改部分值
4jmap: 生成堆快照
jmap 可以生成java应用程序的对快照和对象的统计信息
C:\Users\shj>jmap
Usage:
jmap [option] <pid>
(to connect to running process)
jmap [option] <executable <core>
(to connect to a core file)
jmap [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)
where <option> is one of:
<none> to print same info as Solaris pmap
-heap to print java heap summary
-histo[:live] to print histogram of java object heap; if the "live"
suboption is specified, only count live objects
-clstats to print class loader statistics
-finalizerinfo to print information on objects awaiting finalization
-dump:<dump-options> to dump java heap in hprof binary format
dump-options:
live dump only live objects; if not specified,
all objects in the heap are dumped.
format=b binary format
file=<file> dump heap to <file>
Example: jmap -dump:live,format=b,file=heap.bin <pid>
-F force. Use with -dump:<dump-options> <pid> or -histo
to force a heap dump or histogram when <pid> does not
respond. The "live" suboption is not supported
in this mode.
-h | -help to print this help message
-J<flag> to pass <flag> directly to the runtime system
使用jmap生成对象统计,并将统计结果写到文件中
C:\Users\shj>jmap -histo 42040 >D:aaa.txt
文件内容
num #instances #bytes class name
----------------------------------------------
1: 463974 53658416 [C
2: 289049 6937176 java.lang.String
3: 51414 2728904 [Ljava.lang.String;
4: 45269 1810760 java.util.LinkedHashMap$Entry
...
2796: 1 16 sun.util.locale.provider.TimeZoneNameUtility$TimeZoneNameGetter
2797: 1 16 sun.util.resources.LocaleData
2798: 1 16 sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total 1222041 81174248
显示了内存中的实例数量和合计
生成堆快照
C:\Users\shj>jmap -dump:format=b,file=D:\dump.hprof 42040
Dumping heap to D:\dump.hprof ...
Heap dump file created
5 jhat: 对对快照进行分析,并启动一个http服务,可以通过浏览器,浏览快照信息
jhat可以分析堆快照
C:\Users\shj>jhat D:\dump.hprof
Reading from D:\dump.hprof...
Dump file created Tue Oct 17 17:40:27 CST 2023
Snapshot read, resolving...
Resolving 1366122 objects...
Chasing references, expect 273 dots.................................................................................................................................................................................................................................................................................
Eliminating duplicate references.................................................................................................................................................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
在浏览器中输入http://127.0.0.1:7000/
选中一个类查看
还提供一个查询功能
可以点击oqlhelp,查看对应的语法
6 jstack: 快速得到线程堆栈,自动进行死锁检查,输出死锁线程信息
查询线程堆栈
C:\Users\shj>jstack
Usage:
jstack [-l] <pid>
(to connect to running process)
jstack -F [-m] [-l] <pid>
(to connect to a hung process)
jstack [-m] [-l] <executable> <core>
(to connect to a core file)
jstack [-m] [-l] [server_id@]<remote server IP or hostname>
(to connect to a remote debug server)
Options:
-F to force a thread dump. Use when jstack <pid> does not respond (process is hung)
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
-h or -help to print this help message
C:\Users\shj>jstack -l 42040 >D:\stack.txt
txt内容
2023-10-17 17:56:19
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.281-b09 mixed mode):
"DestroyJavaVM" #41 prio=5 os_prio=0 tid=0x0000018c70ab5800 nid=0x4860 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"http-nio-8080-Acceptor" #40 daemon prio=5 os_prio=0 tid=0x0000018c70ab4000 nid=0x487c runnable [0x000000527feff000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:424)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:252)
- locked <0x0000000776446818> (a java.lang.Object)
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:548)
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:79)
at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:129)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
...
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000018c6cca5000 nid=0xab58 in Object.wait() [0x000000527deff000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000006c3636fb0> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000006c3636fb0> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
Locked ownable synchronizers:
- None
"VM Thread" os_prio=2 tid=0x0000018c6cc7b000 nid=0x8410 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000018c521d9800 nid=0x9528 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000018c521db000 nid=0x4428 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000018c521dc000 nid=0x2b70 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000018c521dd800 nid=0x6d78 runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x0000018c521df800 nid=0x2b68 runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000018c521e0800 nid=0x421c runnable
"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000018c521e3800 nid=0xa900 runnable
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000018c521e4800 nid=0x98bc runnable
"VM Periodic Task Thread" os_prio=2 tid=0x0000018c6f29c000 nid=0x8b9c waiting on condition
JNI global references: 1398
如果出现线程死锁,可以快速查到
一个死锁进程
package com.example.juc.thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadA extends Thread{
String names;
static Lock lock1 = new ReentrantLock();
static Lock lock2 = new ReentrantLock();
public ThreadA(String name) {
this.names = name;
}
@Override
public void run() {
if(names=="1"){
try {
lock1.lockInterruptibly();
Thread.sleep(1000);
lock2.lockInterruptibly();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
try {
lock2.lockInterruptibly();
Thread.sleep(1000);
lock1.lockInterruptibly();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ThreadA threadA = new ThreadA("1");
ThreadA threadB = new ThreadA("B");
threadA.start();
threadB.start();
}
}
查看线程信息
...
Found one Java-level deadlock:
=============================
"Thread-1":
waiting for ownable synchronizer 0x000000076c0e3168, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "Thread-0"
"Thread-0":
waiting for ownable synchronizer 0x000000076c0e3198, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c0e3168> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at com.example.juc.thread.ThreadA.run(ThreadA.java:29)
"Thread-0":
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076c0e3198> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:897)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at com.example.juc.thread.ThreadA.run(ThreadA.java:21)
Found 1 deadlock.
7 jstatd
jstatd 起一个rmi服务,可以远程监控本机
C:\Users\shj>jstatd
Could not create remote object
access denied ("java.util.PropertyPermission" "java.rmi.server.ignoreSubClasses" "write")
java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.rmi.server.ignoreSubClasses" "write")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.security.AccessController.checkPermission(AccessController.java:886)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.System.setProperty(System.java:792)
at sun.tools.jstatd.Jstatd.main(Jstatd.java:139)
这是由于jstatd 没有权限,
将以下内容写到文件中,命名文件为 jstatd.all.policy
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
执行命令
jstatd -J-Djava.security.policy=D:/jstatd.all.policy
启动jstatd,默认端口为1099
使用jps查看
C:\Users\shj>jps
49056 Jstatd
47172 Launcher
41064
42040 JucApplication
47656 Jps
C:\Users\shj>jps localhost:1099
49056 Jstatd
47172 Launcher
41064
42040 JucApplication
46120 Jps
查看42040进场的gc信息
C:\Users\shj>jstat -gcutil 42040@localhost:1099
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 98.11 33.49 8.47 92.21 89.11 9 0.074 2 0.097 0.171