JVM学习——虚拟机性能监控与故障处理工具

13 篇文章 0 订阅

定位一个系统的出现的问题,知识、经验是关键基础,数据是一句,工作是运用知识处理数据的手段。数据包括:运行日志、异常对战、GC日志、线程快照、堆转存储快照等等。经常使用适当的虚拟机监控和分析的工具可以加快我们分析数据、定位解决问题的速度。

JDK的命令行工具

在JDK的bin目录中有命令行工具:
在这里插入图片描述这些主要用于监控虚拟机和故障处理的工具,文件大小普遍不大,是因为这些命令行工具大多数是jdk/lib/tools.jar类库的一层薄包装,主要功能代码是由tools类库中实现的。

快照文件:是把系统某个状态下的各种数据记录在一个文件里,就如同人照相一样,相片显示的是你那个时间的一个状态。系统快照就是系统的“照片”,虚拟机制作了系统快照后就不用启动虚拟系统了,直接恢复快照就行了,你制作快照的时候,系统什么状态,回复后就是什么状态,包括你打开的软件的状态

JDK监控和故障处理工具

名称主要作用
jpsJVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程
jstatJVM Statistiics Monitoring Tool,用于手机HotSpot虚拟机各方面的运行数据
jinfoConfiguration Info for Java ,显示虚拟机配置信息
jmapMemory Map for Java,生成虚拟机的内存转储快照(headdump文件)
jhatJVM Heap Dump Browser,用于分析headdump文件,它会简历一个HTTP/HTML服务器,让用户可以在浏览器上分析结果
jstackStack Trace for Java,显示虚拟机的线程快照
  • jps:虚拟机进程状况工具(JVM Process Status Tool)

    可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class, main()函数所在的类)名称以及这些进程的本地虚拟机唯一ID(Local Virtual Machine Identifier,LVMID)。虽然功能比较单一,但它是使用频率最高的JDK命令行工具,因为其他的JDK工具大多数需要输入它查询到的LVMID来确定要监控哪一个虚拟机进程。对于本地虚拟机进程来说,LVMIN与操作系统的进程ID(Process Identifier,PID)是一致的,使用Windows的任务管理器或UNIX的ps命令也可以查询到虚拟机进程LVMID,但如果 同时开启多个虚拟机进程无法根据进程名称定位时,那就只能依赖jps命令显示主类的功能才能分区了。
    这里我运行了一个死锁的程序,运行工具类jps后的结果。可以看到Deadlock的进程ID:49112
    在这里插入图片描述在这里插入图片描述在dos命令下根据jps工具查询到的进程id也能找到进程。

jps工具主要选项

选项作用
-q只输出LVMID,省略主类的名称
-m输出虚拟机进程启动时传递给主类main()函数的参数
-l输出主类的全名,如果进程执行的是jar包,输出jar路径
-v输出虚拟机进程启动的JVM参数

调试这些命令

C:\Program Files\Java\jdk1.8.0_144\bin>jps -l
48608 org.jetbrains.idea.maven.server.RemoteMavenServer
49472 com.vma.howjava.charactor.Deadlock
48292 sun.tools.jps.Jps
49300 org.jetbrains.jps.cmdline.Launcher
49800 org.jetbrains.kotlin.daemon.KotlinCompileDaemon
48172

C:\Program Files\Java\jdk1.8.0_144\bin>jps -q
48608
49472
48820
49300
49800
48172

C:\Program Files\Java\jdk1.8.0_144\bin>jps -v
48608 RemoteMavenServer -Djava.awt.headless=true -Didea.version==2018.3.4 -Xmx76
8m -Didea.maven.embedder.version=3.5.4 -Dfile.encoding=GBK
49472 Deadlock -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:61027,suspen
d=y,server=n -javaagent:C:\Users\Administrator\.IntelliJIdea2018.3\system\captur
eAgent\debugger-agent.jar -Dfile.encoding=UTF-8
49300 Launcher -Xmx700m -Djava.awt.headless=true -Djava.endorsed.dirs="" -Djdt.c
ompiler.useSingleThread=true -Dpreload.project.path=G:/idea-workspace/richard-de
mo -Dpreload.config.path=C:/Users/Administrator/.IntelliJIdea2018.3/config/optio
ns -Dcompile.parallel=false -Drebuild.on.dependency.change=true -Djava.net.prefe
rIPv4Stack=true -Dio.netty.initialSeedUniquifier=-5773405132924965522 -Dfile.enc
oding=GBK -Duser.language=zh -Duser.country=CN -Didea.paths.selector=IntelliJIde
a2018.3 -Didea.home.path=E:\JetBrains\IntelliJ IDEA 2018.3.4 -Didea.config.path=
C:\Users\Administrator\.IntelliJIdea2018.3\config -Didea.plugins.path=C:\Users\A
dministrator\.IntelliJIdea2018.3\config\plugins -Djps.log.dir=C:/Users/Administr
ator/.IntelliJIdea2018.3/system/log/build-log -Djps.fallback.jdk.home=E:/JetBrai
ns/IntelliJ IDEA 2018.3.4/jre64 -Djps.fallback.jdk.version=1.8.0_152-release -Di
o.netty.noUnsafe=true -Djava.io.tmpdir=C:/Users/Administrator/.IntelliJIdea2018.
3/system/compile-server/richard-demo_cd8c6d76/_temp_ -Djps.backward.ref.index.b
49588 Jps -Denv.class.path=.;C:\Program Files\Java\jdk1.8.0_144\lib;C:\Program F
iles\Java\jdk1.8.0_144\lib\tools.jar;F:\apache-jmeter-5.0\lib\ext\ApacheJMeter_c
ore.jar; F:\apache-jmeter-5.0\lib\jorphan.jar;  -Dapplication.home=C:\Program Fi
les\Java\jdk1.8.0_144 -Xms8m
49800 KotlinCompileDaemon -Djava.awt.headless=true -Djava.rmi.server.hostname=12
7.0.0.1 -Xmx700m -Dkotlin.incremental.compilation=true
48172  -Xms128m -Xmx750m -XX:ReservedCodeCacheSize=240m -XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50 -ea -Dsun.io.useCanonCaches=false -Djava.net.pref
erIPv4Stack=true -Djdk.http.auth.tunneling.disabledSchemes="" -XX:+HeapDumpOnOut
OfMemoryError -XX:-OmitStackTraceInFastThrow -Duser.language=zh -Djb.vmOptionsFi
le=E:\JetBrains\IntelliJ IDEA 2018.3.4\bin\idea64.exe.vmoptions -Didea.jre.check
=true -Dide.native.launcher=true -Didea.paths.selector=IntelliJIdea2018.3 -XX:Er
rorFile=C:\Users\Administrator\java_error_in_idea_%p.log -XX:HeapDumpPath=C:\Use
rs\Administrator\java_error_in_idea.hprof

C:\Program Files\Java\jdk1.8.0_144\bin>jps -m
48608 RemoteMavenServer
48768 Jps -m
49472 Deadlock
49300 Launcher E:/JetBrains/IntelliJ IDEA 2018.3.4/lib/aether-transport-http-1.1
.0.jar;E:/JetBrains/IntelliJ IDEA 2018.3.4/lib/aether-impl-1.1.0.jar;E:/JetBrain
s/IntelliJ IDEA 2018.3.4/lib/aether-connector-basic-1.1.0.jar;E:/JetBrains/Intel
liJ IDEA 2018.3.4/lib/plexus-component-annotations-1.6.jar;E:/JetBrains/IntelliJ
 IDEA 2018.3.4/lib/commons-lang3-3.4.jar;E:/JetBrains/IntelliJ IDEA 2018.3.4/lib
/maven-model-3.3.9.jar;E:/JetBrains/IntelliJ IDEA 2018.3.4/lib/jps-model.jar;E:/
JetBrains/IntelliJ IDEA 2018.3.4/lib/commons-codec-1.10.jar;E:/JetBrains/Intelli
J IDEA 2018.3.4/lib/slf4j-api-1.7.25.jar;E:/JetBrains/IntelliJ IDEA 2018.3.4/lib
/jps-builders-6.jar;E:/JetBrains/IntelliJ IDEA 2018.3.4/lib/annotations.jar;E:/J
etBrains/IntelliJ IDEA 2018.3.4/lib/idea_rt.jar;E:/JetBrains/IntelliJ IDEA 2018.
3.4/lib/netty-resolver-4.1.30.Final.jar;E:/JetBrains/IntelliJ IDEA 2018.3.4/lib/
netty-codec-4.1.30.Final.jar;E:/JetBrains/IntelliJ IDEA 2018.3.4/lib/asm-all-7.0
.jar;E:/JetBrains/IntelliJ IDEA 2018.3.4/lib
49800 KotlinCompileDaemon --daemon-runFilesPath C:\Users\Administrator\AppData\L
ocal\kotlin\daemon --daemon-autoshutdownIdleSeconds=7200 --daemon-compilerClassp
ath E:\JetBrains\IntelliJ IDEA 2018.3.4\plugins\Kotlin\kotlinc\lib\kotlin-compil
er.jar;C:\Program Files\Java\jdk1.8.0_144\lib\tools.jar
48172
  • jstat:虚拟机统计信息监视工具(JVM Statistics Monitoring Tool)
    是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形界面,只停供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。
    jstat命令格式为:
    jstat [ option vmid [interval [s|ms] [count] ] ]
C:\Program Files\Java\jdk1.8.0_144\bin>jstat -gc 49472
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU
   CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000

对于命令格式中的VMID与LVMID需要特别的说明一下:如果是本地虚拟机进程,VMID与LVMID是一致的,如果是远程虚拟机进程,那么VMID的格式应当是:
(这里暂时不去实现,等以后想起来再去弄)
[protocol:] [//] lvmid [@hostname [:port]/servername]
参数interval和count代表查询间隔和次数,如果省略这两个参数,说明只查询一次。假设需要每250毫秒查询一次进程49472垃圾收集情况,一共查询20次,那么命令应当是:
jstat -gc 49472 250 20

C:\Program Files\Java\jdk1.8.0_144\bin>jstat -gc 49472 250 20
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU
   CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000

jstat命名输出后各个参数

参数意义
S0C年轻代中第一个survivor(幸存区)的容量 (字节)
S1C年轻代中第二个survivor(幸存区)的容量 (字节)
S0U年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC年轻代中Eden(伊甸园)的容量 (字节)
EU年轻代中Eden(伊甸园)目前已使用空间 (字节)
OCOld代的容量 (字节)
OUOld代目前已使用空间 (字节)
PCPerm(持久代)的容量 (字节)
PUPerm(持久代)目前已使用空间 (字节)
YGC从应用程序启动到采样时年轻代中gc次数
YGCT从应用程序启动到采样时年轻代中gc所用时间(s)
FGC从应用程序启动到采样时old代(全gc)gc次数
FGCT从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT从应用程序启动到采样时gc用的总时间(s)

这些参数部分内容很多,就不多写了。大家去搜搜都有,用的时候调出来就好了

jstat工具主要选项

选项作用
class监视类的装载、卸载数量、总空间以及装载所耗费的时间
-gc监视Java堆状况,包括Eden区、两个Surivor区、老年代、永久带等的容量、已用空间、GC时间合计等信息
-gccapacity监视内容与-gc基本相同,但输出主要关注Java堆各个区域使用的最大空间、最小空间
-gcutil监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比
-gccause与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因
-gcnew监视新生代GC状况
-gcnewcapacity监视内容与-gcnew基本相同,输出主要关注使用的最大空间、最小空间
-gcold监视老年代GC状况
-gcoldcapacity监视内容与-gcold相同,输出主要关注使用到的最大、最小空间
-gcpermcapacity输出永久代使用到的最大空间、最小空间
-compiler输出JIT编译器编译过的方法、耗时等消息
–printcompilation输出已经被JIT编译的方法

调试

C:\Program Files\Java\jdk1.8.0_144\bin>jstat -class 49472
Loaded  Bytes  Unloaded  Bytes     Time
   660  1307.9        0     0.0       1.31

C:\Program Files\Java\jdk1.8.0_144\bin>jstat -gc 49472
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU
   CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
5120.0 5120.0  0.0    0.0   33280.0   8011.1   87552.0      0.0     4480.0 781.2
  384.0   75.9       0    0.000   0      0.000    0.000

C:\Program Files\Java\jdk1.8.0_144\bin>jstat -gccapacity 49472
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC
       OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC

 43520.0 692224.0  43520.0 5120.0 5120.0  33280.0    87552.0  1384448.0    87552
.0    87552.0      0.0 1056768.0   4480.0      0.0 1048576.0    384.0      0
 0

C:\Program Files\Java\jdk1.8.0_144\bin>jstat -gcutil 49472
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT

  0.00   0.00  24.07   0.00  17.44  19.76      0    0.000     0    0.000    0.00
0

C:\Program Files\Java\jdk1.8.0_144\bin>jstat -gccause 49472
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  LGCC                 GCC
  0.00   0.00  24.07   0.00  17.44  19.76      0    0.000     0    0.000    0.00
0 No GC                No GC

C:\Program Files\Java\jdk1.8.0_144\bin>jstat -gcnew 49472
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
5120.0 5120.0    0.0    0.0 15  15    0.0  33280.0   8011.1      0    0.000


C:\Program Files\Java\jdk1.8.0_144\bin>jstat -gcnewcapacity 49472
  NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX
    EC      YGC   FGC
   43520.0   692224.0    43520.0 230400.0   5120.0 230400.0   5120.0   691200.0
   33280.0     0     0

C:\Program Files\Java\jdk1.8.0_144\bin>jstat -gcold 49472
   MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT
    GCT
  4480.0    781.2    384.0     75.9     87552.0         0.0      0     0    0.00
0    0.000

C:\Program Files\Java\jdk1.8.0_144\bin>jstat -gcoldcapacity 49472
   OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT
    87552.0   1384448.0     87552.0     87552.0     0     0    0.000    0.000


C:\Program Files\Java\jdk1.8.0_144\bin>jstat -compiler 49472
Compiled Failed Invalid   Time   FailedType FailedMethod
      50      0       0     0.07          0

C:\Program Files\Java\jdk1.8.0_144\bin>jstat -printcompilation 49472
Compiled  Size  Type Method
      50     35    1 java/nio/ByteBuffer arrayOffset
  • jinfo:Java配置信息工具(Configuration Info for Java)
    jinfo的作用是实时地查看和调整虚拟机各个参数。使用jps命名的-v参数可以查看虚拟机启动时显示指定的参数列表,但如果想知道未被显示指定的参数的系统默认值,除了去找资料外,就只能使用jinfo的-flag选项进行查询了,jinfo还可以使用-sysprops选项把虚拟机进程的System.getProperties()的内容打印出来。
    jinfo命令格式:
    **jinfo [option] pid

调试

48608 org.jetbrains.idea.maven.server.RemoteMavenServer
49472 com.vma.howjava.charactor.Deadlock
49300 org.jetbrains.jps.cmdline.Launcher
49800 org.jetbrains.kotlin.daemon.KotlinCompileDaemon
36060 sun.tools.jps.Jps
48172

C:\Program Files\Java\jdk1.8.0_144\bin>jinfo 49472
Attaching to process ID 49472, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.144-b01
Java System Properties:

java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.144-b01
sun.boot.library.path = C:\Program Files\Java\jdk1.8.0_144\jre\bin
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = ;
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level =
sun.java.launcher = SUN_STANDARD
user.script =
user.country = CN
user.dir = G:\idea-workspace\richard-demo
java.vm.specification.name = Java Virtual Machine Specification
intellij.debug.agent = true
java.runtime.version = 1.8.0_144-b01
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = C:\Program Files\Java\jdk1.8.0_144\jre\lib\endorsed
line.separator =

java.io.tmpdir = C:\Users\ADMINI~1\AppData\Local\Temp\
java.vm.specification.vendor = Oracle Corporation
user.variant =
os.name = Windows 8.1
sun.jnu.encoding = GBK
java.library.path = C:\Program Files\Java\jdk1.8.0_144\bin;C:\Windows\Sun\Java\b
in;C:\Windows\system32;C:\Windows;F:\maven\apache-maven-3.5.4\bin\;C:\ProgramDat
a\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C
:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Java\jdk1.8.0_144\bi
n;C:\Program Files\Java\jdk1.8.0_144\jre\bin;F:\apache-jmeter-5.0\bin;E:\Program
 Files\Git\cmd;C:\Program Files\MySQL\MySQL Server 5.5\bin;C:\Program Files\Redi
s\;C:\Program Files\Python37\Scripts\;C:\Program Files\Python37\;E:\VSCode\Micro
soft VS Code\bin;.
jboss.modules.system.pkgs = com.intellij.rt
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 6.3
user.home = C:\Users\Administrator
user.timezone =
java.awt.printerjob = sun.awt.windows.WPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
user.name = Administrator
java.class.path = C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Pro
gram Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_1
44\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\e
xt\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Prog
ram Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8
.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\loca
ledata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program
 Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_14
4\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext
\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\P
rogram Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.
8.0_144\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;C:
\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_
144\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Pr
ogram Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files\Java
\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\reso
urces.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;G:\idea-workspace\ri
chard-demo\how-java\target\classes;F:\maven\repository\org\springframework\boot\
spring-boot-starter\2.1.4.RELEASE\spring-boot-starter-2.1.4.RELEASE.jar;F:\maven
\repository\org\springframework\boot\spring-boot\2.1.4.RELEASE\spring-boot-2.1.4
.RELEASE.jar;F:\maven\repository\org\springframework\spring-context\5.1.6.RELEAS
E\spring-context-5.1.6.RELEASE.jar;F:\maven\repository\org\springframework\sprin
g-aop\5.1.6.RELEASE\spring-aop-5.1.6.RELEASE.jar;F:\maven\repository\org\springf
ramework\spring-beans\5.1.6.RELEASE\spring-beans-5.1.6.RELEASE.jar;F:\maven\repo
sitory\org\springframework\spring-expression\5.1.6.RELEASE\spring-expression-5.1
.6.RELEASE.jar;F:\maven\repository\org\springframework\boot\spring-boot-autoconf
igure\2.1.4.RELEASE\spring-boot-autoconfigure-2.1.4.RELEASE.jar;F:\maven\reposit
ory\org\springframework\boot\spring-boot-starter-logging\2.1.4.RELEASE\spring-bo
ot-starter-logging-2.1.4.RELEASE.jar;F:\maven\repository\ch\qos\logback\logback-
classic\1.2.3\logback-classic-1.2.3.jar;F:\maven\repository\ch\qos\logback\logba
ck-core\1.2.3\logback-core-1.2.3.jar;F:\maven\repository\org\apache\logging\log4
j\log4j-to-slf4j\2.11.2\log4j-to-slf4j-2.11.2.jar;F:\maven\repository\org\apache
\logging\log4j\log4j-api\2.11.2\log4j-api-2.11.2.jar;F:\maven\repository\org\slf
4j\jul-to-slf4j\1.7.26\jul-to-slf4j-1.7.26.jar;F:\maven\repository\javax\annotat
ion\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;F:\maven\repositor
y\org\springframework\spring-core\5.1.6.RELEASE\spring-core-5.1.6.RELEASE.jar;F:
\maven\repository\org\springframework\spring-jcl\5.1.6.RELEASE\spring-jcl-5.1.6.
RELEASE.jar;F:\maven\repository\org\yaml\snakeyaml\1.23\snakeyaml-1.23.jar;F:\ma
ven\repository\org\slf4j\slf4j-api\1.7.26\slf4j-api-1.7.26.jar;E:\JetBrains\Inte
lliJ IDEA 2018.3.4\lib\idea_rt.jar;C:\Users\Administrator\.IntelliJIdea2018.3\sy
stem\captureAgent\debugger-agent.jar
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = com.vma.howjava.charactor.Deadlock
java.home = C:\Program Files\Java\jdk1.8.0_144\jre
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.8.0_144
java.ext.dirs = C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext;C:\Windows\Sun\Ja
va\lib\ext
sun.boot.class.path = C:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;C
:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Program Files\Java\jdk1.8.0_
144\jre\lib\sunrsasign.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;C
:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0
_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\
Program Files\Java\jdk1.8.0_144\jre\classes
java.vendor = Oracle Corporation
file.separator = \
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.desktop = windows
sun.cpu.isalist = amd64

VM Flags:
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=134217728 -XX:Ma
xHeapSize=2126512128 -XX:MaxNewSize=708837376 -XX:MinHeapDeltaBytes=524288 -XX:N
ewSize=44564480 -XX:OldSize=89653248 -XX:+UseCompressedClassPointers -XX:+UseCom
pressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocati
on -XX:+UseParallelGC
Command line:  -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:61027,suspen
d=y,server=n -javaagent:C:\Users\Administrator\.IntelliJIdea2018.3\system\captur
eAgent\debugger-agent.jar -Dfile.encoding=UTF-8
  • jmap:Java内存映像工具(Memory Map for Java)
    jmap命令用于生成堆转储快照(一般称为headdump或dump文件)。jmap的作用并不仅仅是为了获取dump文件,它还可以查询finalize执行队列、Java堆和永久代的详细信息,如空间使用率、当前用的是哪种收集器等。
    和jinfo命令一样,jmap有不少功能在Windows平台下受限的,除了生成dump文件的-dump选项和用于查看每一个类的实例、空间占用统计的-histo选项所在所有操作系统提供之外,其余选项只能在Linux/Solaris下使用
    jmap命令格式:
    jmap [option] vmid

    jmap工具主要选项

    选项作用
    -dump生成Java堆转储快照。格式为: -dump:[live, ]format = b, file=,其中live子参数说明是否只dump出存活的对象
    -finalizerinfo显示在F-Queue中等待Finalizer线程执行finalize方法的对象。只在Linux/Solaris平台下有效
    -heap显示Java堆详细信息,如使用哪种回收器、参数配置、分代状况等。只在Linux/Solaris平台有效
    -histo显示堆中对象统计信息,包括类、实例数据、合计容量
    permstat以ClassLoader为统计口径显示永久代状态。只在Linux/Solaris平台下有效
    -F当前虚拟机进程对-dump选项没有响应时,可使用这个选项强制生成dump快照。只在Linux/Solaris平台下有效

这个命令在Linux启动,于是将毕设项目部署到Linux后,来调试一下。
数据量太大了,使用贴不上来,贴几个数据量小的

[root@localhost bin]# jmap -F 1467
Attaching to process ID 1467, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.11-b03
0x0000000000400000	7K	/usr/local/java/jdk1.8.0_11/bin/java
0x00007f27ee0e2000	89K	/usr/local/java/jdk1.8.0_11/jre/lib/amd64/libnio.so
0x00007f27eeaf3000	108K	/usr/local/java/jdk1.8.0_11/jre/lib/amd64/libnet.so
0x00007f27eed09000	48K	/usr/local/java/jdk1.8.0_11/jre/lib/amd64/libmanagement.so
0x00007f27ffbb8000	127K	/usr/local/java/jdk1.8.0_11/jre/lib/amd64/libzip.so
0x00007f27ffdd4000	219K	/usr/local/java/jdk1.8.0_11/jre/lib/amd64/libjava.so
0x00007f2804011000	60K	/usr/lib64/libnss_files-2.17.so
0x00007f2804224000	64K	/usr/local/java/jdk1.8.0_11/jre/lib/amd64/libverify.so
0x00007f2804433000	42K	/usr/lib64/librt-2.17.so
0x00007f280463b000	1110K	/usr/lib64/libm-2.17.so
0x00007f280493d000	15684K	/usr/local/java/jdk1.8.0_11/jre/lib/amd64/server/libjvm.so
0x00007f2805861000	2101K	/usr/lib64/libc-2.17.so
0x00007f2805c2e000	18K	/usr/lib64/libdl-2.17.so
0x00007f2805e32000	105K	/usr/local/java/jdk1.8.0_11/lib/amd64/jli/libjli.so
0x00007f2806049000	138K	/usr/lib64/libpthread-2.17.so
0x00007f2806265000	159K	/usr/lib64/ld-2.17.so

[root@localhost bin]# jmap -finalizerinfo 1467
Attaching to process ID 1467, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.11-b03
Number of objects pending for finalization: 0


  • jhat:虚拟机堆转储快照分析工具(JVM Heap Analysis Tool)
    Sun JDK提供jhat命令与jmap搭配使用,来分析jamp生成的堆转储快照。jhat内置了一个微型的HTTP/HTML服务器,生成的dump文件的分析结果后,可以在浏览器中查看。不过实事求是地说,在实际工作中,除非手上真的没有别的工具看用,否则一般不会直接使用jaht命令来分许dump文件,主要原因有二:一是一般不会部署应用程序的服务器上直接分析dump文件,即使可以这样做,也会尽量将dump文件复制到其他机器上分析,因为分析工作是一个耗时且消耗硬件资源的过程,既然都要在其他机器上分析,就没有必要受到命令行工具的限制了;另一个原因是jhat分析功能相对来说比较简陋。相比于VisualVM,以及专业用语分析dump文件的Eclipse Memory Analyze、IBM HeapAnalyzer等工具,都能实现比jhat更加强大更加专业的分析功能。

    分析刚刚生成的快照文件

     C:\Program Files\Java\jdk1.8.0_144\bin>jhat eclipse.bin
    Reading from eclipse.bin...
    Dump file created Thu Apr 25 14:02:08 CST 2019
    Snapshot read, resolving...
    Resolving 27035 objects...
    Chasing references, expect 5 dots.....
    Eliminating duplicate references.....
    Snapshot resolved.
    Started HTTP server on port 7000
    Server is ready.

打开浏览器输入:http://localhost:7000/
在这里插入图片描述

  • jstack:Java堆栈跟踪工具(Stack Trace for Java)
    jstack命令用于生成虚拟机当前时刻的线程快照。线程快照急速当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程死锁、死循环、请求外部资源导致的长时间等待都是导致线程长时间挺多你的常见原因。线程出现挺多你的时候通过jstack来查看各个线程的调用堆栈,就可以自动有没有响应的线程到底在后台做些什么事情、或者等待着什么资源。
    jstack 命令格式
    jstack [option] vmid

jstack工具主要选项

选项作用
-F当正常输出的请求不被响应时,强制输出线程堆栈
-l除堆栈外,显示关于锁的附加信息
-m如果调用到本地方法,可以显示C/C++的堆栈

调试

C:\Program Files\Java\jdk1.8.0_144\bin>jstack -l 52008
2019-04-25 14:23:15
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode):

"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x0000000000c3e800 nid=0x6d9c waiting o
n condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

 Locked ownable synchronizers:
      - None

"Thread-1" #12 prio=5 os_prio=0 tid=0x0000000018d2b800 nid=0xc96c waiting for mo
nitor entry [0x000000001989f000]
 java.lang.Thread.State: BLOCKED (on object monitor)
      at com.vma.howjava.charactor.Deadlock$2.run(Deadlock.java:58)
      - waiting to lock <0x00000000d5de1968> (a com.vma.howjava.charactor.Hero
)
      - locked <0x00000000d5de1980> (a com.vma.howjava.charactor.Hero)

 Locked ownable synchronizers:
      - None

"Thread-0" #11 prio=5 os_prio=0 tid=0x0000000018d2a000 nid=0xccbc waiting for mo
nitor entry [0x000000001979f000]
 java.lang.Thread.State: BLOCKED (on object monitor)
      at com.vma.howjava.charactor.Deadlock$1.run(Deadlock.java:36)
      - waiting to lock <0x00000000d5de1980> (a com.vma.howjava.charactor.Hero
)
      - locked <0x00000000d5de1968> (a com.vma.howjava.charactor.Hero)

 Locked ownable synchronizers:
      - None

"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x0000000018c61800 nid=0xcc9c r
unnable [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

 Locked ownable synchronizers:
      - None

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

 Locked ownable synchronizers:
      - None

"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x0000000018bd3000 nid=0xc89
0 waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

 Locked ownable synchronizers:
      - None

"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x0000000018bd2800 nid=0xcf4
8 waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

 Locked ownable synchronizers:
      - None

"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x0000000018b96800 nid=0x39d
8 runnable [0x000000001919f000]
 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 <0x00000000d5e33a30> (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 <0x00000000d5e33a30> (a java.io.InputStreamReader)
      at java.io.BufferedReader.readLine(BufferedReader.java:389)
      at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:
64)

 Locked ownable synchronizers:
      - None

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x00000000177ac800 nid=0xc948 w
aiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE

 Locked ownable synchronizers:
      - None

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

 Locked ownable synchronizers:
      - None

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001773a800 nid=0xbf8c in Obje
ct.wait() [0x0000000018a9f000]
 java.lang.Thread.State: WAITING (on object monitor)
      at java.lang.Object.wait(Native Method)
      - waiting on <0x00000000d5c08ec8> (a java.lang.ref.ReferenceQueue$Lock)
      at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
      - locked <0x00000000d5c08ec8> (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)

 Locked ownable synchronizers:
      - None

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000002bd2000 nid=0x681
0 in Object.wait() [0x000000001899e000]
 java.lang.Thread.State: WAITING (on object monitor)
      at java.lang.Object.wait(Native Method)
      - waiting on <0x00000000d5c06b68> (a java.lang.ref.Reference$Lock)
      at java.lang.Object.wait(Object.java:502)
      at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
      - locked <0x00000000d5c06b68> (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=0x0000000017718000 nid=0x76d8 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002af8800 nid=0x65c0 runn
able

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002afa000 nid=0xc804 runn
able

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002afb800 nid=0xcd84 runn
able

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002afd000 nid=0x3064 runn
able

"VM Periodic Task Thread" os_prio=2 tid=0x0000000018cba000 nid=0xcdd4 waiting on
condition

JNI global references: 33


Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x0000000002bdb0f8 (object 0x00000000d5de1968, a com.v
ma.howjava.charactor.Hero),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x0000000002bd87b8 (object 0x00000000d5de1980, a com.v
ma.howjava.charactor.Hero),
which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
      at com.vma.howjava.charactor.Deadlock$2.run(Deadlock.java:58)
      - waiting to lock <0x00000000d5de1968> (a com.vma.howjava.charactor.Hero
)
      - locked <0x00000000d5de1980> (a com.vma.howjava.charactor.Hero)
"Thread-0":
      at com.vma.howjava.charactor.Deadlock$1.run(Deadlock.java:36)
      - waiting to lock <0x00000000d5de1980> (a com.vma.howjava.charactor.Hero
)
      - locked <0x00000000d5de1968> (a com.vma.howjava.charactor.Hero)

Found 1 deadlock.

发现了我的死锁问题…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值