作者:小傅哥
博客:https://bugstack.cn
沉淀、分享、成长,让自己和他人都能有所收获!😄
用都用不到怎么学?
没有场景、没有诉求,怎么学习这些似乎用不上知识点。
其实最好的方式就是归纳、整理、实践、输出,一套组合拳下来,你就掌握了这个系列的知识了。
但在当前阶段可能真的用不上,JVM是一个稳定服务,哪能天天出问题,哪需要你老排查。又不是像你写的代码那样!
可是知识的学习就是把你垫基到更高层次后,才有机会接触更有意思的工作和技术创新。如果只是单纯的学几个指令,其实并没有多有意思。但让你完成一套全链路监控,里面需要含有一次方法调用的整体耗时、执行路径、参数信息、异常结果、GC次数、堆栈数据、分代内容等等的时候,那么你的知识储备够开发一个这样的系统吗?
好,先上图看看本文要讲啥,再跟着小傅哥的步伐往下走。
谢飞机,小记!
,周末休息在家无聊,把已经上灰了的JVM虚拟机学习翻出来。
谢飞机:呱...呱...,喂大哥,这个,这个JVM虚拟机看啥呀。
面试官:看啥?不知道从哪开始?嗯,那你从问题点下手!
谢飞机:啥问题点呢,我就是不知道自己不会啥,也不知道问你啥。
面试官:啊!那我问你个,怎么通过JVM故障处理工具,查看JVM启动时参数都配置了什么呢?
谢飞机:这个!?不道呀!
面试官:那你熟悉的监控指令都有啥,如果问你堆内存统计如何统计,你可知晓!?
谢飞机:也不知道,哈哈哈,好像知道要去看啥了!
面试官:去吧,带着问题看,看完整理出来!
jps(JVM Process Status Tool),它的功能与ps命令类似,可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一ID(Local Virtual Machine Identifier,LVMID),类似于 ps -ef | grep java 的功能。
这小家伙虽然不大,功能又单一。但可以说基本你用其他命令都得先用它,来查询到LVMID来确定要监控的是哪个虚拟机进程。
命令格式
jps [ options ] [ hostid ]
选项列表
选项 | 描述 |
---|---|
-q | 只输出进程ID,忽略主类信息 |
-l | 输出主类全名,或者执行JAR包则输出路径 |
-m | 输出虚拟机进程启动时传递给主类main()函数的参数 |
-v | 输出虚拟机进程启动时的JVM参数 |
E:\itstack\git\github.com\interview>jps -q 104928 111552 26852 96276 59000 8460 76188
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
也是非常常用的一个参数选项。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
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
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 -lm 127.0.0.1
jcmd,是从jdk1.7开始新发布的 JVM 相关信息诊断工具,可以用它来导出堆和线程信息、查看Java进程、执行GC、还可以进行采样分析(jmc 工具的飞行记录器)。注意其使用条件是只能在被诊断的JVM同台sever上,并且具有相同的用户和组(user and group).
命令格式
jcmd <pid | main class> <command ...|PerfCounter.print|-f file>
pid,接收诊断命令请求的进程ID
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
E:\itstack\git\github.com\interview>jcmd 111552 VM.uptime 111552: 583248.912 s
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 ...
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;
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)
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
E:\itstack\git\github.com\interview>jcmd 111552 GC.heap_dump C:\Users\xiaofuge1\Desktop\_dump_0110 111552: Heap dump file created
E:\itstack\git\github.com\interview>jcmd 111552 help 111552: The following commands are available: JFR.stop JFR.start JFR.dump JFR.check
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)
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
jstat(JVM Statistics Monitoring Tool),用于监视虚拟机各种运行状态信息。它可以查看本地或者远程虚拟机进程中,类加载、内存、垃圾收集、即时编译等运行时数据。
命令格式
`jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
`
[protocol:][//]lvmid[@hostname[:port]/servername]
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,元空间统计 |
E:\itstack\git\github.com\interview>jstat -class 111552 Loaded Bytes Unloaded Bytes Time 5835 12059.6 37 53.5 3.88
E:\itstack\git\github.com\interview>jstat -compiler 111552 Compiled Failed Invalid Time FailedType FailedMethod 3642 0 0 5.61 0
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
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
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
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
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
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
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
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
E:\itstack\git\github.com\interview>jstat -printcompilation 111552 Compiled Size Type Method 3642 9 1 java/io/BufferedWriter min
jmap(Memory Map for Java),用于生成堆转储快照(heapdump文件)。
jmap 的作用除了获取堆转储快照,还可以查询finalize执行队列、Java 堆和方法区的详细信息。
命令格式
jmap [ option ] pid
选项列表
选项 | 描述 |
---|---|
-dump | 生成 Java 堆转储快照。 |
-finalizerinfo | 显示在F-Queue中等待Finalizer线程执行finalize方法的对象。Linux平台 |
-heap | 显示 Java 堆详细信息,比如:用了哪种回收器、参数配置、分代情况。Linux平台 |
-histo | 显示堆中对象统计信息,包括类、实例数量、合计容量 |
-permstat | 显示永久代内存状态,jdk1.7,永久代 |
-F | 当虚拟机进程对 -dump 选项没有响应式,可以强制生成快照。Linux平台 |
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
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)
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
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
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/
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)
JConsole( Java Monitoring and Management Console),是一款基于JMX( Java Manage-ment
Extensions) 的可视化监视管理工具。
它的功能主要是对系统进行收集和参数调整,不仅可以在虚拟机本身管理还可以开发在软件上,是开放的服务,有相应的代码API调用。
JConsole 启动
JConsole 使用
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
监控结果