JVM故障处理工具,使用总结

Stella981
• 阅读 638

持续坚持原创输出,点击蓝字关注我吧

JVM故障处理工具,使用总结

作者:小傅哥
博客:https://bugstack.cn

沉淀、分享、成长,让自己和他人都能有所收获!😜

目录

  • 一、前言

  • 二、面试题

  • 三、基础故障处理工具

  • 1. jps 虚拟机进程状况

  • 2. jcmd 虚拟机诊断命令

  • 3. jinfo Java配置信息工具

  • 4. jstat 收集虚拟机运行数据

  • 5. jmap 内存映射工具

  • 6. jhat 堆转储快照分析工具

  • 7. jstack Java堆栈跟踪工具

  • 四、可视化故障处理工具

  • 1. jconsole,Java监视与管理控制台

  • 2. VisualVM,多合故障处理工具

  • 五、总结

  • 六、系列推荐

一、前言

用都用不到怎么学?

没有场景、没有诉求,怎么学习这些似乎用不上知识点。

其实最好的方式就是归纳、整理、实践、输出,一套组合拳下来,你就掌握了这个系列的知识了。

但在当前阶段可能真的用不上,JVM是一个稳定服务,哪能天天出问题,哪需要你老排查。又不是像你写的代码那样!

可是知识的学习就是把你垫基到更高层次后,才有机会接触更有意思的工作和技术创新。如果只是单纯的学几个指令,其实并没有多有意思。但让你完成一套全链路监控,里面需要含有一次方法调用的整体耗时、执行路径、参数信息、异常结果、GC次数、堆栈数据、分代内容等等的时候,那么你的知识储备够开发一个这样的系统吗?

好,先上图看看本文要讲啥,再跟着小傅哥的步伐往下走。

JVM故障处理工具,使用总结

JVM 故障处理工具

二、面试题

谢飞机,小记!,周末休息在家无聊,把已经上灰了的JVM虚拟机学习翻出来。

「谢飞机」:呱...呱...,喂大哥,这个,这个JVM虚拟机看啥呀。

「面试官」:看啥?不知道从哪开始?嗯,那你从问题点下手!

「谢飞机」:啥问题点呢,我就是不知道自己不会啥,也不知道问你啥。

「面试官」:啊!那我问你个,怎么通过JVM故障处理工具,查看JVM启动时参数都配置了什么呢?

「谢飞机」:这个!?不道呀!

「面试官」:那你熟悉的监控指令都有啥,如果问你堆内存统计如何统计,你可知晓!?

「谢飞机」:也不知道,哈哈哈,好像知道要去看啥了!

「面试官」:去吧,带着问题看,看完整理出来!

三、基础故障处理工具

1. jps 虚拟机进程状况

jps(JVM Process Status Tool),它的功能与ps命令类似,可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一ID(Local Virtual Machine Identifier,LVMID),类似于 ps -ef | grep java 的功能。

这小家伙虽然不大,功能又单一。但可以说基本你用其他命令都得先用它,来查询到LVMID来确定要监控的是哪个虚拟机进程。

「命令格式」

jps [ options ] [ hostid ]

  • options:选项、参数,不同的参数可以输出需要的信息

  • hostid:远程查看

「选项列表」

选项

描述

-q

只输出进程ID,忽略主类信息

-l

输出主类全名,或者执行JAR包则输出路径

-m

输出虚拟机进程启动时传递给主类main()函数的参数

-v

输出虚拟机进程启动时的JVM参数

1.1 jps -q,只列出进程ID

E:\itstack\git\github.com\interview>jps -q 104928 111552 26852 96276 59000 8460 76188

1.2 jps -l,输出当前运行类全称

E:\itstack\git\github.com\interview>jps -l 111552 org/netbeans/Main 26852 96276 org.jetbrains.jps.cmdline.Launcher 59000 62184 sun.tools.jps.Jps 8460 org/netbeans/Main 76188 sun.tools.jstatd.Jstatd

  • 用这个命令输出的内容就清晰多了, -l 也是非常常用的一个参数选项。

1.3 jps -m,列出传给main()函数的参数

E:\itstack\git\github.com\interview>jps -m 111552 Main --branding visualvm --cachedir C:\Users\xiaofuge\AppData\Local\VisualVM\Cache/8u131 --openid 3041391569375200 26852 96276 Launcher C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/plugins/java/lib/javac2.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/plugins/java/lib/aether-api-1.1.0.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/lib/jna-platform.jar;C:/Program Fi les/JetBrains/IntelliJ IDEA 2019.3.1/lib/guava-27.1-jre.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/lib/httpclient-4.5.10.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/lib/forms-1.1-preview.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/plu gins/java/lib/aether-connector-basic-1.1.0.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/plugins/java/lib/maven-model-builder-3.3.9.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/lib/jps-model.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/plu gins/java/lib/maven-model-3.3.9.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/plugins/java/lib/aether-impl-1.1.0.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2019.3.1/lib/gson-2.8.5.jar;C:/Program File 59000 16844 Jps -m 8460 Main --branding visualvm --cachedir C:\Users\xiaofuge\AppData\Local\VisualVM\Cache/8u131 --openid 3041414336579200 76188 Jstatd

1.4 jps -v,输出虚拟机进程启动时JVM参数[-Xms24m -Xmx256m]

E:\itstack\git\github.com\interview>jps -v 111552 Main -Xms24m -Xmx256m -Dsun.jvmstat.perdata.syncWaitMs=10000 -Dsun.java2d.noddraw=true -Dsun.java2d.d3d=false -Dnetbeans.keyring.no.master=true -Dplugin.manager.install.global=false --add-exports=java.desktop/sun.awt=ALL-UNNAMED --add-exports=jdk.jvmstat/sun .jvmstat.monitor.event=ALL-UNNAMED --add-exports=jdk.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED --add-exports=java.desktop/sun.swing=ALL-UNNAMED --add-exports=jdk.attach/sun.tools.attach=ALL-UNNAMED --add-modules=java.activation -XX:+IgnoreUnrecognizedVMOptions -Djdk. home=C:/Program Files/Java/jdk1.8.0_161 -Dnetbeans.home=C:\Program Files\Java\jdk1.8.0_161\lib\visualvm\platform -Dnetbeans.user=C:\Users\xiaofuge1\AppData\Roaming\VisualVM\8u131 -Dnetbeans.default_userdir_root=C:\Users\xiaofuge1\AppData\Roaming\VisualVM -XX:+H eapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\xiaofuge1\AppData\Roaming\VisualVM\8u131\var\log\heapdump.hprof -Dsun.awt.keepWorkingSetOnMinimize=true -Dnetbeans.dirs=C:\Program Files\Java\jdk1.8.0_161\lib\visualvm\visualvm;C:\Program 59000  -Dfile.encoding=UTF-8 -Xms128m -Xmx1024m -XX:MaxPermSize=256m 76188 Jstatd -Denv.class.path=.;C:\Program Files\Java\jre1.8.0_161\lib;C:\Program Files\Java\jre1.8.0_161\lib\tool.jar; -Dapplication.home=C:\Program Files\Java\jdk1.8.0_161 -Xms8m -Djava.security.policy=jstatd.all.policy

1.5 jps -lv 127.0.0.1,输出远程机器信息

jps 链接远程输出JVM信息,需要注册RMI,否则会报错 RMI Registry not available at 127.0.0.1

注册RMI开启 jstatd 在你的 C:\Program Files\Java\jdk1.8.0_161\bin 目录下添加名称为 jstatd.all.policy 的文件。无其他后缀

「jstatd.all.policy」 文件内容如下:

grant codebase "file:${java.home}/../lib/tools.jar" {    permission java.security.AllPermission; };

添加好配置文件后,在 bin 目录下注册添加的 jstatd.all.policy 文件:C:\Program Files\Java\jdk1.8.0_161\bin>jstatd -J-Djava.security.policy=jstatd.all.policy

顺利的话现在就可以查看原创机器JVM信息了,如下:

E:\itstack\git\github.com\interview>jps -l 127.0.0.1 111552 org/netbeans/Main 26852 96276 org.jetbrains.jps.cmdline.Launcher 36056 sun.tools.jps.Jps 59000 8460 org/netbeans/Main 76188 sun.tools.jstatd.Jstatd

  • 也可以组合使用 jps 的选项参数,比如: jps -lm 127.0.0.1

2. jcmd 虚拟机诊断命令

jcmd,是从jdk1.7开始新发布的 JVM 相关信息诊断工具,可以用它来导出堆和线程信息、查看Java进程、执行GC、还可以进行采样分析(jmc 工具的飞行记录器)。注意其使用条件是只能在被诊断的JVM同台sever上,并且具有相同的用户和组(user and group).

「命令格式」

jcmd <pid | main class> <command ...|PerfCounter.print|-f file>

  • pid,接收诊断命令请求的进程ID

  • main class,接收诊断命令请求的进程main类。

  • command,接收诊断命令请求的进程main类。

  • PerfCounter.print,打印目标 Java 进程上可用的性能计数器。

  • -f file,从文件file中读取命令,然后在目标Java进程上调用这些命令。

  • -l,查看所有进程列表信息。

  • -h、-help,查看帮助信息。

2.1 jcmd pid VM.flags,查看JVM启动参数

E:\itstack\git\github.com\interview>jcmd 111552 VM.flags 111552: -XX:CICompilerCount=4 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\xiaofuge1\AppData\Roaming\VisualVM\8u131\var\log\heapdump.hprof -XX:+IgnoreUnrecognizedVMOptions -XX:InitialHeapSize=25165824 -XX:MaxHeapSize=268435456 -XX:MaxNewSize=89128960 -XX:Min HeapDeltaBytes=524288 -XX:NewSize=8388608 -XX:OldSize=16777216 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC

2.2 jcmd pid VM.uptime,查看JVM运行时长

E:\itstack\git\github.com\interview>jcmd 111552 VM.uptime 111552: 583248.912 s

2.3 jcmd pid PerfCounter.print,查看JVM性能相关参数

E:\itstack\git\github.com\interview>jcmd 111552 PerfCounter.print 111552: java.ci.totalTime=56082522 java.cls.loadedClasses=5835 java.cls.sharedLoadedClasses=0 java.cls.sharedUnloadedClasses=0 java.cls.unloadedClasses=37 ...

2.4 jcmd pid GC.class_histogram,查看系统中类的统计信息

`E:\itstack\git\github.com\interview>jcmd 111552 GC.class_histogram
111552:

 num     #instances         #bytes  class name

   1:         50543        3775720  [C
   2:          3443        2428248  [I
   3:         50138        1203312  java.lang.String
   4:         25351         811232  java.util.HashMap$Node
   5:          6263         712208  java.lang.Class
   6:          3134         674896  [B
   7:          6687         401056  [Ljava.lang.Object;
   8:          2468         335832  [Ljava.util.HashMap$Node;
`

2.5 jcmd pid Thread.print,查看线程堆栈信息

`E:\itstack\git\github.com\interview>jcmd 111552 Thread.print
111552:
2021-01-10 23:31:13
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode):

"Computes values in handlers" #52 daemon prio=5 os_prio=0 tid=0x0000000019839000 nid=0x16014 waiting for monitor entry [0x0000000026bce000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.sun.tools.visualvm.core.model.ModelFactory.getModel(ModelFactory.java:76)
        - waiting to lock <0x00000000f095bcf8> (a com.sun.tools.visualvm.jvmstat.application.JvmstatApplication)
        at com.sun.tools.visualvm.application.jvm.JvmFactory.getJVMFor(JvmFactory.java:45)
        at com.sun.tools.visualvm.application.options.Open.openApplication(Open.java:108)
        at com.sun.tools.visualvm.application.options.Open.process(Open.java:93)
        at org.netbeans.spi.sendopts.Option$1.process(Option.java:348)
        at org.netbeans.api.sendopts.CommandLine.process(CommandLine.java:278)
        at org.netbeans.modules.sendopts.HandlerImpl.execute(HandlerImpl.java:23)
        at org.netbeans.modules.sendopts.Handler.cli(Handler.java:30)
        at org.netbeans.CLIHandler.notifyHandlers(CLIHandler.java:195)
        at org.netbeans.core.startup.CLICoreBridge.cli(CLICoreBridge.java:43)
        at org.netbeans.CLIHandler.notifyHandlers(CLIHandler.java:195)
        at org.netbeans.CLIHandler$Server$1ComputingAndNotifying.run(CLIHandler.java:1176)
`

2.6 jcmd pid VM.system_properties,查看JVM系统参数

E:\itstack\git\github.com\interview>jcmd 111552 VM.system_properties 111552: #Sun Jan 13 23:33:19 CST 2021 java.vendor=Oracle Corporation netbeans.user=C\:\\Users\\xiaofuge1\\AppData\\Roaming\\VisualVM\\8u131 sun.java.launcher=SUN_STANDARD sun.management.compiler=HotSpot 64-Bit Tiered Compilers netbeans.autoupdate.version=1.23 os.name=Windows 10

2.7 jcmd pid GC.heap_dump 路径,导出heap dump文件

E:\itstack\git\github.com\interview>jcmd 111552 GC.heap_dump C:\Users\xiaofuge1\Desktop\_dump_0110 111552: Heap dump file created

  • 导出的文件需要配合 jvisualvm 查看

2.8 jcmd pid help,列出可执行操作

E:\itstack\git\github.com\interview>jcmd 111552 help 111552: The following commands are available: JFR.stop JFR.start JFR.dump JFR.check

2.9 jcmd pid help JFR.stop,查看命令使用

`E:\itstack\git\github.com\interview>jcmd 111552 help JFR.stop
111552:
JFR.stop
Stops a JFR recording

Impact: Low

Permission: java.lang.management.ManagementPermission(monitor)

Syntax : JFR.stop [options]

Options: (options must be specified using the  or = syntax)
        name : [optional] Recording name,.e.g "My Recording" (STRING, no default value)
        recording : [optional] Recording number, see JFR.check for a list of available recordings (JLONG, -1)
        discard : [optional] Skip writing data to previously specified file (if any) (BOOLEAN, false)
        filename : [optional] Copy recording data to file, e.g. "C:\Users\user\My Recording.jfr" (STRING, no default value)
        compress : [optional] GZip-compress "filename" destination (BOOLEAN, false)
`

3. jinfo Java配置信息工具

jinfo(Configuration Info for Java),实时查看和调整JVM的各项参数。

在上面讲到 jps -v 指令时,可以看到它把虚拟机启动时显式的参数列表都打印出来了,但如果想更加清晰的看具体的一个参数或者想知道未被显式指定的参数时,就可以通过 jinfo -flag 来查询了。

「命令格式」

jinfo [ option ] pid

「使用方式」

`E:\itstack\git\github.com\interview>jinfo -flag MetaspaceSize 111552
-XX:MetaspaceSize=21807104

E:\itstack\git\github.com\interview>jinfo -flag MaxMetaspaceSize 111552
-XX:MaxMetaspaceSize=18446744073709486080

E:\itstack\git\github.com\interview>jinfo -flag HeapDumpPath 111552
-XX:HeapDumpPath=C:\Users\xiaofuge\AppData\Roaming\VisualVM\8u131\var\log\heapdump.hprof
`

  • 各种JVM参数你都可以去查询,这样更加方便的只把你要的显示出来。

4. jstat 收集虚拟机运行数据

jstat(JVM Statistics Monitoring Tool),用于监视虚拟机各种运行状态信息。它可以查看本地或者远程虚拟机进程中,类加载、内存、垃圾收集、即时编译等运行时数据。

「命令格式」

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

  • vmid:如果是查看远程机器,需要按照此格式: [protocol:][//]lvmid[@hostname[:port]/servername]

  • interval和count,表示查询间隔和次数,比如每隔1000毫秒查询一次进程ID的gc收集情况,每次查询5次。 jstat -gc 111552 1000 5

「选项列表」

选项

描述

-class

监视类加载、卸载数量、总空间以及类装载所耗费时长

-gc

监视 Java 堆情况,包括Eden区、2个 Survivor区、老年代、永久代或者jdk1.8元空间等,容量、已用空间、垃圾收集时间合计等信息

-gccapacity

监视内容与-gc基本一致,但输出主要关注 Java 堆各个区域使用到的最大、最小空间

-gcutil

监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比

-gccause

与 -gcutil 功能一样,但是会额外输出导致上一次垃圾收集产生的原因

-gcnew

监视新生代垃圾收集情况

-gcnewcapacity

监视内容与 -gcnew 基本相同,输出主要关注使用到的最大、最小空间

-gcold

监视老年代垃圾收集情况

-gcoldcapacity

监视内容与 -gcold 基本相同,输出主要关注使用到的最大、最小空间

-compiler

输出即时编译器编译过的方法、耗时等信息

-printcompilation

输出已经被即时编译的方法

-gcpermcapacity

jdk1.7 及以下,永久代空间统计

-gcmetacapacity

jdk1.8,元空间统计

  • jstat 的监视选项还是非常多的,但最常用的主要有上面这些。

4.01 jstat -class,类加载统计

E:\itstack\git\github.com\interview>jstat -class 111552 Loaded  Bytes  Unloaded  Bytes     Time   5835 12059.6       37    53.5       3.88

  • Loaded,加载class的数量

  • Bytes:所占用空间大小

  • Unloaded:未加载数量

  • Bytes:未加载占用空间

  • Time:时间

4.02 jstat -compiler,编译统计

E:\itstack\git\github.com\interview>jstat -compiler 111552 Compiled Failed Invalid   Time   FailedType FailedMethod     3642      0       0     5.61          0

  • Compiled:编译数量

  • Failed:失败数量

  • Invalid:不可用数量

  • Time:时间

  • FailedType:失败类型

  • FailedMethod:失败方法

4.03 jstat -gc,垃圾回收统计

E:\itstack\git\github.com\interview>jstat -gc 111552  S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT 1024.0 512.0   0.0    0.0   77312.0    35.1    39424.0    13622.9   37120.0 34423.3 5376.0 4579.4     60    0.649  52      3.130    3.779

  • S0C、S1C,第一个和第二个幸存区大小

  • S0U、S1U,第一个和第二个幸存区使用大小

  • EC、EU,伊甸园的大小和使用

  • OC、OU,老年代的大小和使用

  • MC、MU,方法区的大小和使用

  • CCSC、CCSU,压缩类空间大小和使用

  • YGC、YGCT,年轻代垃圾回收次数和耗时

  • FGC、FGCT,老年代垃圾回收次数和耗时

  • GCT,垃圾回收总耗时

4.04 jstat -gccapacity,堆内存统计

E:\itstack\git\github.com\interview>jstat -gccapacity 111552  NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC   8192.0  87040.0  80384.0 1024.0  512.0  77312.0    16384.0   175104.0    39424.0    39424.0      0.0 1081344.0  37120.0      0.0 1048576.0   5376.0     60    52

  • NGCMN、NGCMX,新生代最小和最大容量

  • NGC,当前新生代容量

  • S0C、S1C,第一和第二幸存区大小

  • EC,伊甸园区的大小

  • OGCMN、OGCMX,老年代最小和最大容量

  • OGC、OC,当前老年代大小

  • MCMN、MCMX,元数据空间最小和最大容量

  • MC,当前元空间大小

  • CCSMN、CCSMX,压缩类最小和最大空间

  • YGC,年轻代GC次数

  • FGC,老年代GC次数

4.05 jstat -gcnewcapacity,新生代内存统计

E:\itstack\git\github.com\interview>jstat -gcnewcapacity 111552   NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC     8192.0    87040.0    80384.0  28672.0   1024.0  28672.0    512.0    86016.0    77312.0    60    52

  • NGCMN、NGCMX,新生代最小和最大容量

  • NGC,当前新生代容量

  • S0CMX,最大幸存0区大小

  • S0C,当前幸存0区大小

  • S1CMX,最大幸存1区大小

  • S1C,当前幸存1区大小

  • ECMX,最大伊甸园区大小

  • EC,当前伊甸园区大小

  • YGC,年轻代垃圾回收次数

  • FGC,老年代回收次数

4.06 jstat -gcnew,新生代垃圾回收统计

E:\itstack\git\github.com\interview>jstat -gcnew 111552  S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT 1024.0  512.0    0.0    0.0  3  15  512.0  77312.0     70.2     60    0.649

  • S0C、S1C,第一和第二幸存区大小

  • S0U、S1U,第一和第二幸存区使用

  • TT,对象在新生代存活的次数

  • MTT,对象在新生代存活的最大次数

  • DSS:期望的幸存区大小

  • EC,伊甸园区的大小

  • EU,伊甸园区的使用

  • YGC,年轻代垃圾回收次数

  • YGCT,年轻代垃圾回收消耗时间

4.07 jstat -gcold,老年代垃圾回收统计

E:\itstack\git\github.com\interview>jstat -gcold 111552    MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT  37120.0  34423.3   5376.0   4579.4     39424.0     13622.9     60    52    3.130    3.779

  • MC、MU,方法区的大小和使用

  • CCSC、CCSU,压缩类空间大小和使用

  • OC、OU,老年代大小和使用

  • YGC,年轻代垃圾回收次数

  • FGC,老年代垃圾回收次数

  • FGCT,老年代垃圾回收耗时

  • GCT,垃圾回收总耗时

4.08 jstat -gcoldcapacity,老年代内存统计

E:\itstack\git\github.com\interview>jstat -gcoldcapacity 111552    OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT     16384.0    175104.0     39424.0     39424.0    60    52    3.130    3.779

  • OGCMN、OGCMX,老年代最小和最大容量

  • OGC,当前老年代大小

  • OC,老年代大小

  • YGC,年轻代垃圾回收次数

  • FGC,老年代垃圾回收次数

  • FGCT,老年代垃圾回收耗时

  • GCT,垃圾回收消耗总耗时

4.09 jstat -gcmetacapacity,元空间统计

E:\itstack\git\github.com\interview>jstat -gcmetacapacity 111552    MCMN       MCMX        MC       CCSMN      CCSMX       CCSC     YGC   FGC    FGCT     GCT        0.0  1081344.0    37120.0        0.0  1048576.0     5376.0    60    52    3.130    3.779

  • MCMN、MCMX,元空间最小和最大容量

  • MC,当前元数据空间大小

  • CCSMN、CCSMX,压缩类最小和最大空间

  • CCSC,压缩类空间大小

  • YGC,年轻代垃圾回收次数

  • FGC,老年代垃圾回收次数

  • FGCT,老年代垃圾回收耗时

  • GCT,垃圾回收消耗总耗时

4.10 jstat -gcutil,垃圾回收统计

E:\itstack\git\github.com\interview>jstat -gcutil 111552   S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   0.00   0.00   0.09  34.55  92.74  85.18     60    0.649    52    3.130    3.779

  • S0、S1、幸存1区和2区,当前使用占比

  • E,伊甸园区使用占比

  • O,老年代区使用占比

  • M,元数据区使用占比

  • CCS,压缩类使用占比

  • YGC,年轻代垃圾回收次数

  • FGC,老年代垃圾回收次数

  • FGCT,老年代垃圾回收耗时

  • GCT,垃圾回收消耗总耗时

4.11 jstat -printcompilation,JVM编译方法统计

E:\itstack\git\github.com\interview>jstat -printcompilation 111552 Compiled  Size  Type Method     3642      9    1 java/io/BufferedWriter min

  • Compiled:最近编译方法的数量

  • Size:最近编译方法的字节码数量

  • Type:最近编译方法的编译类型

  • Method:方法名标识

5. jmap 内存映射工具

jmap(Memory Map for Java),用于生成堆转储快照(heapdump文件)。

jmap 的作用除了获取堆转储快照,还可以查询finalize执行队列、Java 堆和方法区的详细信息。

「命令格式」

jmap [ option ] pid

  • option:选项参数

  • pid:需要打印配置信息的进程ID

  • executable:产生核心dump的Java可执行文件

  • core:需要打印配置信息的核心文件

  • server-id:可选的唯一id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器

  • remote server IP or hostname:远程调试服务器的IP地址或主机名

「选项列表」

选项

描述

-dump

生成 Java 堆转储快照。

-finalizerinfo

显示在F-Queue中等待Finalizer线程执行finalize方法的对象。Linux平台

-heap

显示 Java 堆详细信息,比如:用了哪种回收器、参数配置、分代情况。Linux平台

-histo

显示堆中对象统计信息,包括类、实例数量、合计容量

-permstat

显示永久代内存状态,jdk1.7,永久代

-F

当虚拟机进程对 -dump 选项没有响应式,可以强制生成快照。Linux平台

5.1 jmap,打印共享对象映射

E:\itstack\git\github.com\interview>jmap 111552 Attaching to process ID 111552, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.161-b12 0x000000005b4a0000      1632K   C:\Program Files\Java\jdk1.8.0_161\jre\bin\awt.dll 0x000000005b8c0000      264K    C:\Program Files\Java\jdk1.8.0_161\jre\bin\t2k.dll 0x000000005b910000      284K    C:\Program Files\Java\jdk1.8.0_161\jre\bin\fontmanager.dll 0x000000005b960000      224K    C:\Program Files\Java\jdk1.8.0_161\jre\bin\splashscreen.dll 0x000000005b9a0000      68K     C:\Program Files\Java\jdk1.8.0_161\jre\bin\nio.dll

5.2 jmap -heap,堆详细信息

`E:\itstack\git\github.com\interview>jmap -heap 111552
Attaching to process ID 111552, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 268435456 (256.0MB)
   NewSize                  = 8388608 (8.0MB)
   MaxNewSize               = 89128960 (85.0MB)
   OldSize                  = 16777216 (16.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)
`

5.3 jmap -clstats,打印加载类

`E:\itstack\git\github.com\interview> jmap -clstats 111552
Attaching to process ID 111552, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.161-b12
finding class loader instances ..done.
computing per loader stat ..done.
please wait.. computing liveness.................................................................liveness analysis may be inaccurate ...
class_loader    classes bytes   parent_loader   alive?  type

     3779    6880779   null          live    
0x00000000f03853b8      57      132574  0x00000000f031aac8      live    org/netbeans/StandardModule$OneModuleClassLoader@0x00000001001684f0
0x00000000f01b9b98      0       0       0x00000000f031aac8      live    org/netbeans/StandardModule$OneModuleClassLoader@0x00000001001684f0
0x00000000f005b280      0       0       0x00000000f031aac8      live    java/util/ResourceBundle$RBClassLoader@0x00000001000c6ae0
0x00000000f01dfa98      0       0       0x00000000f031aac8      live    org/netbeans/StandardModule$OneModuleClassLoader@0x00000001001684f0
0x00000000f01ec518      79      252894  0x00000000f031aac8      live    org/netbeans/StandardModule$OneModuleClassLoader@0x00000001001684f0
`

5.4 jmap -dump,堆转储文件

E:\itstack\git\github.com\interview>jmap -dump:live,format=b,file=C:/Users/xiaofuge/Desktop/heap.bin 111552 Dumping heap to C:\Users\xiaofuge\Desktop\heap.bin ... Heap dump file created

6. jhat 堆转储快照分析工具

jhat(JVM Heap Analysis Tool),与jmap配合使用,用于分析jmap生成的堆转储快照。

jhat内置了一个小型的http/web服务器,可以把堆转储快照分析的结果,展示在浏览器中查看。不过用途不大,基本大家都会使用其他第三方工具。

「命令格式」

jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>

「命令使用」

E:\itstack\git\github.com\interview>jhat -port 8090 C:/Users/xiaofuge1/Desktop/heap.bin Reading from C:/Users/xiaofuge1/Desktop/heap.bin... Dump file created Wed Jan 13 16:53:47 CST 2021 Snapshot read, resolving... Resolving 246455 objects... Chasing references, expect 49 dots................................................. Eliminating duplicate references................................................. Snapshot resolved. Started HTTP server on port 8090 Server is ready.

http://localhost:8090/」

JVM故障处理工具,使用总结

jhat -port 8090

7. jstack Java堆栈跟踪工具

jstack(Stack Trace for Java),用于生成虚拟机当前时刻的线程快照(threaddump、javacore)。

线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因,如:线程死锁、死循环、请求外部资源耗时较长导致挂起等。

线程出现听顿时通过jstack来查看各个线程的调用堆栈,就可以获得没有响应的线程在搞什么鬼。

「命令格式」

jstack [ option ] vmid

「选项参数」

选项

描述

-F

当正常输出的请求不被响应时,强制输出线程堆栈

-l

除了堆栈外,显示关于锁的附加信息

-m

如果调用的是本地方法的话,可以显示c/c++的堆栈

「命令使用」

`E:\itstack\git\github.com\interview>jstack 111552
2021-01-10 23:15:03
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode):

"Inactive RequestProcessor thread [Was:StdErr Flush/org.netbeans.core.startup.logging.PrintStreamLogger]" #59 daemon prio=1 os_prio=-2 tid=0x000000001983a800 nid=0x688 in Object.wait() [0x0000000017fbf000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:1939)
        - locked <0x00000000fab31d88> (a java.lang.Object)
`

  • 在验证使用的过程中,可以尝试写一个死循环的线程,之后通过jstack查看线程信息。

四、可视化故障处理工具

1. jconsole,Java监视与管理控制台

JConsole( Java Monitoring and Management Console),是一款基于JMX( Java Manage-ment Extensions) 的可视化监视管理工具。

它的功能主要是对系统进行收集和参数调整,不仅可以在虚拟机本身管理还可以开发在软件上,是开放的服务,有相应的代码API调用。

「JConsole 启动」

JVM故障处理工具,使用总结

JConsole 启动

「JConsole 使用」

JVM故障处理工具,使用总结

JConsole 使用

2. VisualVM,多合故障处理工具

VisualVM( All-in-One Java Troubleshooting Tool),是功能最强大的运行监视和故障处理工具之一。

它除了常规的运行监视、故障处理外,还可以做性能分析等工作。因为它的通用性很强,对应用程序影响较小,所以可以直接接入到生产环境中。

「VisualVM IDEA安装」

JVM故障处理工具,使用总结

VisualVM IDEA安装

「VisualVM 使用」

public static void main(String[] args) throws InterruptedException {          Thread.sleep(5000);     ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean();     while (true) {         Enhancer enhancer = new Enhancer();         enhancer.setSuperclass(MetaSpaceOomMock.class);         enhancer.setCallbackTypes(new Class[]{Dispatcher.class, MethodInterceptor.class});         enhancer.setCallbackFilter(new CallbackFilter() {             @Override             public int accept(Method method) {                 return 1;             }             @Override             public boolean equals(Object obj) {                 return super.equals(obj);             }         });         System.out.println(enhancer.createClass().getName() + loadingBean.getTotalLoadedClassCount() + loadingBean.getLoadedClassCount() + loadingBean.getUnloadedClassCount());     } }

「记得调整元空间大小」

-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=80m -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=7397 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

  • 我们就监测这段让元空间溢出的代码, java.lang.OutOfMemoryError: Metaspace

「监控结果」

JVM故障处理工具,使用总结

VisualVM,监控结果

五、总结

  • 本文也是小傅哥在学习《深入理解Java虚拟机》过程中的一个总结,这里包括了很多常用的指令,通过这些指令的学习我们也大概会知道JVM都给我们提供了什么样的监控信息。

  • 其实实际的业务使用中很少通过指令去监控JVM而是有一整套的非入侵全链路监控,在监控服务里与之方法调用时的JVM一并监控,可以让研发人员更快速的排查问题。但这些工具的实现依然是需要这些基础,在有了基础的知识掌握后,可以更好多使用工具。

  • 编程技术类知识的学习一定要实践验证,否则很容易忘记,也很难掌握。当你经过自己手多敲几遍以后,就会有完全不一样的认识。好了,加油!希望本篇文章能为你的薪资鼓鼓劲!

六、系列推荐


bugstack虫洞栈

沉淀、分享、成长,让自己和他人都能有所收获!

作者小傅哥多年从事一线互联网Java开发,从19年开始编写工作和学习历程的技术汇总,旨在为大家提供一个较清晰详细的核心技能学习文档。如果本文能为您提供帮助,请给予支持(关注、点赞、分享)!JVM故障处理工具,使用总结

JVM故障处理工具,使用总结

感谢支持小傅哥原创,欢迎点击在看转发JVM故障处理工具,使用总结

本文分享自微信公众号 - bugstack虫洞栈(bugstack)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Easter79 Easter79
3年前
Thread.start() ,它是怎么让线程启动的呢?
持续坚持原创输出,点击蓝字关注我吧!(https://oscimg.oschina.net/oscnet/78c1be0c0d2547fc88854a8d73d9fc1c.png)作者:小傅哥博客:https://bugstack.cn❝沉淀、分享、成长,让自己和他人都能有所收获!😜❞
Stella981 Stella981
3年前
BATJTMD,大厂招聘,都招什么样Java程序员?
持续坚持原创输出,点击蓝字关注我吧!(https://oscimg.oschina.net/oscnet/1ff569760b5c46afa7f103809ffe6aaf.png)作者:小傅哥博客:https://bugstack.cn沉淀、分享、成长,让自己和他人都能有所收获!😜
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这