关于java:JVM故障处理工具使用总结

33次阅读

共计 19717 个字符,预计需要花费 50 分钟才能阅读完成。

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

积淀、分享、成长,让本人和别人都能有所播种!????

一、前言

用都用不到怎么学?

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

其实最好的形式就是演绎、整顿、实际、输入,一套组合拳下来,你就把握了这个系列的常识了。

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

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

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

二、面试题

谢飞机,小记!,周末劳动在家无聊,把曾经上灰了的 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 <key> or <key>=<value> 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

<bootstrap>     3779    6880779   null          live    <internal>
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/

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 启动

JConsole 应用

2. VisualVM,多合故障解决工具

VisualVM(All-in-One Java Troubleshooting Tool),是性能最弱小的运行监督和故障解决工具之一。

它除了惯例的运行监督、故障解决外,还能够做性能剖析等工作。因为它的通用性很强,对应用程序影响较小,所以能够间接接入到生产环境中。

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

监控后果

五、总结

  • 本文也是小傅哥在学习《深刻了解 Java 虚拟机》过程中的一个总结,这里包含了很多罕用的指令,通过这些指令的学习咱们也大略会晓得 JVM 都给咱们提供了什么样的监控信息。
  • 其实理论的业务应用中很少通过指令去监控 JVM 而是有一整套的非入侵全链路监控,在监控服务里与之办法调用时的 JVM 一并监控,能够让研发人员更疾速的排查问题。但这些工具的实现仍然是须要这些根底,在有了根底的常识把握后,能够更好多应用工具。
  • 编程技术类常识的学习肯定要实际验证,否则很容易遗记,也很难把握。当你通过本人手多敲几遍当前,就会有齐全不一样的意识。好了,加油!心愿本篇文章能为你的薪资鼓鼓劲!

六、系列举荐

  • 为了搞清楚类加载,居然手撸 JVM!
  • JVM 内存模型总结,有各版本 JDK 比照、有元空间 OOM 监控案例、有 Java 版虚拟机,综合学习更容易!
  • HashMap 外围常识,扰动函数、负载因子、扩容链表拆分,深度学习
  • 认知本人的技术栈盲区
  • 线程池的介绍和应用,以及基于 jvmti 设计非入侵监控

正文完
 0