主页 > 手机  > 

JVM在线分析-解决问题的工具一(jinfo,jmap,jstack)

JVM在线分析-解决问题的工具一(jinfo,jmap,jstack)
1. jinfo (base) PS C:\Users\zishi\Desktop> jinfo Usage: jinfo <option> <pid> (to connect to a running process) where <option> is one of: -flag <name> to print the value of the named VM flag #输出对应名称的参数 -flag [+|-]<name> to enable or disable the named VM flag # 开启或者关闭对应名称的参数 只有被标记为 manageable 的参数才可以被动态修改 -flag <name>=<value> to set the named VM flag to the given value #设定对应名称的参数 -flags to print VM flags # 输出全部的参数 -sysprops to print Java system properties #输出系统属性 <no option> to print both VM flags and system properties -? | -h | --help | -help to print this help message (base) PS C:\Users\zishi> jinfo 9368 Java System Properties: #Thu Nov 09 09:05:06 CST 2023 sun.desktop=windows awt.toolkit=sun.awt.windows.WToolkit java.specification.version=11 sun.cpu.isalist=amd64 sun.jnu.encoding=GBK java.class.path=.\\quality-server.jar java.vm.vendor=Oracle Corporation sun.arch.data.model=64 user.variant= catalina.useNaming=false java.vendor.url=https\://openjdk.java.net/ 。。。。略去 (base) PS C:\Users\zishi> jinfo -sysprops 9368 Java System Properties: #Thu Nov 09 09:07:07 CST 2023 sun.desktop=windows awt.toolkit=sun.awt.windows.WToolkit 。。。。略去 (base) PS C:\Users\zishi> jinfo -flags 9368 VM Flags: -XX:CICompilerCount=4 -XX:ConcGCThreads=3 -XX:G1ConcRefinementThreads=10 -XX:G1HeapRegionSize=2097152 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=534773760 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=8524922880 -XX:MaxNewSize=5114953728 -XX:MinHeapDeltaBytes=2097152 -XX:NonNMethodCodeHeapSize=5836300 -XX:NonProfiledCodeHeapSize=122910970 -XX:ProfiledCodeHeapSize=122910970 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation (base) PS C:\Users\zishi> jinfo -flag MaxHeapSize 9368 -XX:MaxHeapSize=8524922880 (base) PS C:\Users\zishi> jinfo -flag MaxHeapSize=8524922883 9368 Exception in thread "main" com.sun.tools.attach.AttachOperationFailedException: flag 'MaxHeapSize' cannot be changed at jdk.attach/sun.tools.attach.VirtualMachineImpl.execute(VirtualMachineImpl.java:130) at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.executeCommand(HotSpotVirtualMachine.java:309) at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.setFlag(HotSpotVirtualMachine.java:282) at jdk.jcmd/sun.tools.jinfo.JInfo.flag(JInfo.java:146) at jdk.jcmd/sun.tools.jinfo.JInfo.main(JInfo.java:127)

查看被标记为 manageable 的参数

$ java -XX:+PrintFlagsFinal -version | grep manageable intx CMSAbortablePrecleanWaitMillis = 100 {manageable} {default} intx CMSTriggerInterval = -1 {manageable} {default} intx CMSWaitDuration = 2000 {manageable} {default} bool HeapDumpAfterFullGC = false {manageable} {default} bool HeapDumpBeforeFullGC = false {manageable} {default} bool HeapDumpOnOutOfMemoryError = false {manageable} {default} ccstr HeapDumpPath = {manageable} {default} uintx MaxHeapFreeRatio = 70 {manageable} {default} uintx MinHeapFreeRatio = 40 {manageable} {default} bool PrintClassHistogram = false {manageable} {default} bool PrintConcurrentLocks = false {manageable} {default} java version "11.0.13" 2021-10-19 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.13+10-LTS-370) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.13+10-LTS-370, mixed mode)

修改参数的值

(base) PS C:\Users\zishi> jinfo -flag MaxHeapFreeRatio 9368 -XX:MaxHeapFreeRatio=70 (base) PS C:\Users\zishi> jinfo -flag MaxHeapFreeRatio=80 9368 (base) PS C:\Users\zishi> jinfo -flag MaxHeapFreeRatio 9368 -XX:MaxHeapFreeRatio=80

开启参数:

(base) PS C:\Users\zishi> jinfo -flag HeapDumpBeforeFullGC 9368 -XX:-HeapDumpBeforeFullGC (base) PS C:\Users\zishi> jinfo -flag +HeapDumpBeforeFullGC 9368 (base) PS C:\Users\zishi> jinfo -flag HeapDumpBeforeFullGC 9368 -XX:+HeapDumpBeforeFullGC

扩展 java -XX:+PrintFlagsInitial 查看所有 JVM 参数启动的初始值 java -XX:+PrintFlagsFinal 查看所有 JVM 参数的最终值 java -XX:+PrintCommandLineFlags 查看哪些已经被用户或者 JVM 设置过的详细的 XX 参数的名称和值

2. jmap (base) PS C:\Users\zishi> jmap Usage: jmap -clstats <pid> to connect to running process and print class loader statistics jmap -finalizerinfo <pid> to connect to running process and print information on objects awaiting finalization jmap -histo[:live] <pid> to connect to running process and print histogram of java object heap if the "live" suboption is specified, only count live objects jmap -dump:<dump-options> <pid> to connect to running process and dump java heap jmap -? -h --help to print this help message dump-options: live dump only live objects; if not specified, all objects in the heap are dumped. format=b binary format file=<file> dump heap to <file> Example: jmap -dump:live,format=b,file=heap.bin <pid> $ jmap -clstats 9368 > a.txt $ cat a.txt | head -n 10 Index Super InstBytes KlassBytes annotations CpAll MethodCount Bytecodes MethodAll ROAll RWAll Total ClassName 1 -1 10510264 504 0 0 0 0 0 24 616 640 [B 2 8286 5545320 1112 0 6816 47 1117 27912 6480 30104 36584 java.lang.reflect.Method 3 18 4025232 616 128 14264 109 4576 71992 18640 69664 88304 java.lang.String 4 18 2461504 592 0 1360 9 213 2720 1488 3520 5008 java.util.concurrent.ConcurrentHashMap$Node 5 -1 2286832 504 0 0 0 0 0 24 616 640 [Ljava.lang.Object; 6 -1 2075104 504 0 0 0 0 0 32 616 648 [Ljava.util.HashMap$Node; 7 18 2013216 584 0 1384 7 149 1816 1152 2952 4104 java.util.HashMap$Node 8 7 1977960 584 0 504 1 10 624 304 1640 1944 java.util.LinkedHashMap$Entry 9 18 1720280 672 0 22112 139 5679 85040 24632 85104 109736 java.lang.Class $ jmap -clstats 9368 | grep com.zishi.docuvate.exception 4077 18 16 552 56 2568 6 282 1576 1448 3504 4952 com.zishi.docuvate.exception.GlobalExceptionHandler 7429 7856 0 624 0 440 3 54 568 464 1368 1832 com.zishi.docuvate.exception.BadRequestException 7430 7856 0 640 0 624 8 105 1472 1072 1952 3024 com.zishi.docuvate.exception.GlobalException

说明:

Index Super InstBytes KlassBytes annotations CpAll MethodCount Bytecodes MethodAll ROAll RWAll Total ClassName: 类的完全限定名

(base) PS C:\Users\zishi> jmap -histo 23152 num #instances #bytes class name (module) ------------------------------------------------------- 1: 1164144 152211432 [B (java.base@11.0.13) 2: 147373 44824568 [I (java.base@11.0.13) 3: 694738 16673712 java.lang.String (java.base@11.0.13) 4: 601819 12621496 [Ljava.lang.Class; (java.base@11.0.13) 5: 107422 9453136 java.lang.reflect.Method (java.base@11.0.13) 6: 113936 7291904 java.net.URL (java.base@11.0.13) 7: 141772 4536704 org.springframework.boot.loader.jar.StringSequence 8: 75593 4434728 [Ljava.lang.Object; (java.base@11.0.13) 9: 178622 4286928 java.lang.StringBuilder (java.base@11.0.13) 10: 102026 4081040 org.springframework.core.annotation.TypeMappedAnnotations 11: 36093 2871384 [Ljava.util.HashMap$Node; (java.base@11.0.13) 12: 88017 2816544 java.util.concurrent.ConcurrentHashMap$Node (java.base@11.0.13) 13: 84459 2702688 org.springframework.core.annotation.TypeMappedAnnotations$MergedAnnotationFinder 14: 82805 2649760 java.util.HashMap$Node (java.base@11.0.13) 15: 64740 2589600 java.util.LinkedHashMap$Entry (java.base@11.0.13) 16: 49166 2359968 java.util.HashMap (java.base@11.0.13) 17: 92807 2227368 org.springframework.boot.loader.jar.JarURLConnection$JarEntryName 18: 12370 2153808 [C (java.base@11.0.13)

说明:

#instances:对象数量 #bytes: 占用内存大小(单位:字节) class name (module): 类的完全限定名

3. jstack (base) PS C:\Users\zishi> jstack Usage: jstack [-l][-e] <pid> (to connect to running process) Options: -l long listing. Prints additional information about locks -e extended listing. Prints additional information about threads -? -h --help -help to print this help message

代码示例:

/** * 当DeadLock类的对象flag==1时(td1),先锁定o1,睡眠500毫秒 * 而td1在睡眠的时候另一个flag==0的对象(td2)线程启动,先锁定o2,睡眠500毫秒 * td1睡眠结束后需要锁定o2才能继续执行,而此时o2已被td2锁定; * td2睡眠结束后需要锁定o1才能继续执行,而此时o1已被td1锁定; * td1、td2相互等待,都需要得到对方锁定的资源才能继续执行,从而死锁。 */ public class DeadLockTest implements Runnable{ public int flag = 1; //静态对象是类的所有对象共享的 private static Object o1 = new Object(), o2 = new Object(); @Override public void run() { System.out.println("flag=" + flag); if (flag == 1) { synchronized (o1) { try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } synchronized (o2) { System.out.println("1"); } } } if (flag == 0) { synchronized (o2) { try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } synchronized (o1) { System.out.println("0"); } } } } public static void main(String[] args) { DeadLockTest td1 = new DeadLockTest(); DeadLockTest td2 = new DeadLockTest(); td1.flag = 1; td2.flag = 0; //td1,td2都处于可执行状态,但JVM线程调度先执行哪个线程是不确定的。 //td2的run()可能在td1的run()之前运行 new Thread(td1).start(); new Thread(td2).start(); } }

编译运行,执行jstack

(base) PS C:\Users\zishi> jstack 21744 2023-11-09 18:47:14 Full thread dump Java HotSpot(TM) 64-Bit Server VM (11.0.13+10-LTS-370 mixed mode): Threads class SMR info: _java_thread_list=0x000001d91fca51a0, length=12, elements={ 0x000001d91fa90800, 0x000001d91fab5800, 0x000001d91fb2b800, 0x000001d91fb2c800, 0x000001d91fb2e000, 0x000001d91fb31000, 0x000001d91fb32800, 0x000001d91fb35800, 0x000001d91fcb6800, 0x000001d91fcbc000, 0x000001d91fcbc800, 0x000001d972982000 } "Reference Handler" #2 daemon prio=10 os_prio=2 cpu=0.00ms elapsed=18.72s tid=0x000001d91fa90800 nid=0x2aac waiting on condition [0x000000aacf8ff000] java.lang.Thread.State: RUNNABLE at java.lang.ref.Reference.waitForReferencePendingList(java.base@11.0.13/Native Method) at java.lang.ref.Reference.processPendingReferences(java.base@11.0.13/Reference.java:241) at java.lang.ref.Reference$ReferenceHandler.run(java.base@11.0.13/Reference.java:213) "Finalizer" #3 daemon prio=8 os_prio=1 cpu=0.00ms elapsed=18.72s tid=0x000001d91fab5800 nid=0x2224 in Object.wait() [0x000000aacf9fe000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(java.base@11.0.13/Native Method) - waiting on <0x0000000623a08fa8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(java.base@11.0.13/ReferenceQueue.java:155) - waiting to re-lock in wait() <0x0000000623a08fa8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(java.base@11.0.13/ReferenceQueue.java:176) at java.lang.ref.Finalizer$FinalizerThread.run(java.base@11.0.13/Finalizer.java:170) "Signal Dispatcher" #4 daemon prio=9 os_prio=2 cpu=0.00ms elapsed=18.70s tid=0x000001d91fb2b800 nid=0x3bcc runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Attach Listener" #5 daemon prio=5 os_prio=2 cpu=0.00ms elapsed=18.70s tid=0x000001d91fb2c800 nid=0x3740 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Service Thread" #6 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=18.70s tid=0x000001d91fb2e000 nid=0xd0c runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #7 daemon prio=9 os_prio=2 cpu=0.00ms elapsed=18.70s tid=0x000001d91fb31000 nid=0x1620 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE No compile task "C1 CompilerThread0" #10 daemon prio=9 os_prio=2 cpu=0.00ms elapsed=18.70s tid=0x000001d91fb32800 nid=0x133c waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE No compile task "Sweeper thread" #11 daemon prio=9 os_prio=2 cpu=0.00ms elapsed=18.70s tid=0x000001d91fb35800 nid=0x1368 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Common-Cleaner" #12 daemon prio=8 os_prio=1 cpu=0.00ms elapsed=18.67s tid=0x000001d91fcb6800 nid=0x1df8 in Object.wait() [0x000000aad01fe000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(java.base@11.0.13/Native Method) - waiting on <0x0000000623bf37f8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(java.base@11.0.13/ReferenceQueue.java:155) - waiting to re-lock in wait() <0x0000000623bf37f8> (a java.lang.ref.ReferenceQueue$Lock) at jdk.internal.ref.CleanerImpl.run(java.base@11.0.13/CleanerImpl.java:148) at java.lang.Thread.run(java.base@11.0.13/Thread.java:834) at jdk.internal.misc.InnocuousThread.run(java.base@11.0.13/InnocuousThread.java:134) "Thread-0" #13 prio=5 os_prio=0 cpu=0.00ms elapsed=18.67s tid=0x000001d91fcbc000 nid=0x39d4 waiting for monitor entry [0x000000aad02ff000] java.lang.Thread.State: BLOCKED (on object monitor) at DeadLockTest.run(DeadLockTest.java:25) - waiting to lock <0x0000000623bf7078> (a java.lang.Object) - locked <0x0000000623bf7068> (a java.lang.Object) at java.lang.Thread.run(java.base@11.0.13/Thread.java:834) "Thread-1" #14 prio=5 os_prio=0 cpu=0.00ms elapsed=18.67s tid=0x000001d91fcbc800 nid=0x7f8 waiting for monitor entry [0x000000aad03ff000] java.lang.Thread.State: BLOCKED (on object monitor) at DeadLockTest.run(DeadLockTest.java:37) - waiting to lock <0x0000000623bf7068> (a java.lang.Object) - locked <0x0000000623bf7078> (a java.lang.Object) at java.lang.Thread.run(java.base@11.0.13/Thread.java:834) "DestroyJavaVM" #15 prio=5 os_prio=0 cpu=15.63ms elapsed=18.67s tid=0x000001d972982000 nid=0x5744 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "VM Thread" os_prio=2 cpu=0.00ms elapsed=18.73s tid=0x000001d91fa8f800 nid=0x222c runnable "GC Thread#0" os_prio=2 cpu=0.00ms elapsed=18.77s tid=0x000001d972996800 nid=0x5144 runnable "G1 Main Marker" os_prio=2 cpu=0.00ms elapsed=18.77s tid=0x000001d972a17800 nid=0x4180 runnable "G1 Conc#0" os_prio=2 cpu=0.00ms elapsed=18.77s tid=0x000001d972a19000 nid=0x3380 runnable "G1 Refine#0" os_prio=2 cpu=0.00ms elapsed=18.75s tid=0x000001d97fde5800 nid=0x2ba4 runnable "G1 Young RemSet Sampling" os_prio=2 cpu=0.00ms elapsed=18.75s tid=0x000001d97fde6800 nid=0x2f8c runnable "VM Periodic Task Thread" os_prio=2 cpu=0.00ms elapsed=18.67s tid=0x000001d91fcb6000 nid=0x2990 waiting on condition JNI global refs: 6, weak refs: 0 Found one Java-level deadlock: ============================= "Thread-0": waiting to lock monitor 0x000001d91fabff80 (object 0x0000000623bf7078, a java.lang.Object), which is held by "Thread-1" "Thread-1": waiting to lock monitor 0x000001d91fabcc80 (object 0x0000000623bf7068, a java.lang.Object), which is held by "Thread-0" Java stack information for the threads listed above: =================================================== "Thread-0": at DeadLockTest.run(DeadLockTest.java:25) - waiting to lock <0x0000000623bf7078> (a java.lang.Object) - locked <0x0000000623bf7068> (a java.lang.Object) at java.lang.Thread.run(java.base@11.0.13/Thread.java:834) "Thread-1": at DeadLockTest.run(DeadLockTest.java:37) - waiting to lock <0x0000000623bf7068> (a java.lang.Object) - locked <0x0000000623bf7078> (a java.lang.Object) at java.lang.Thread.run(java.base@11.0.13/Thread.java:834) Found 1 deadlock.

说明:

Thread-1:线程名 prio:优先级 os_prio:操作系统级别的线程优先级 tid:线程id nid:线程对应本地线程id java.lang.Thread.State:线程状态

可以看到有一个 dead lock Found one Java-level deadlock: jstack还帮我们打印了死锁产生的原因 打印了死锁产生的原因之外,还帮我们定位到了java的代码行数:

Found one Java-level deadlock: ============================= "Thread-0": waiting to lock monitor 0x000001d91fabff80 (object 0x0000000623bf7078, a java.lang.Object), which is held by "Thread-1" "Thread-1": waiting to lock monitor 0x000001d91fabcc80 (object 0x0000000623bf7068, a java.lang.Object), which is held by "Thread-0" Java stack information for the threads listed above: =================================================== "Thread-0": at DeadLockTest.run(DeadLockTest.java:25) - waiting to lock <0x0000000623bf7078> (a java.lang.Object) - locked <0x0000000623bf7068> (a java.lang.Object) at java.lang.Thread.run(java.base@11.0.13/Thread.java:834) "Thread-1": at DeadLockTest.run(DeadLockTest.java:37) - waiting to lock <0x0000000623bf7068> (a java.lang.Object) - locked <0x0000000623bf7078> (a java.lang.Object) at java.lang.Thread.run(java.base@11.0.13/Thread.java:834) Found 1 deadlock.

参考: juejin /post/6957903936657293319#heading-3

标签:

JVM在线分析-解决问题的工具一(jinfo,jmap,jstack)由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“JVM在线分析-解决问题的工具一(jinfo,jmap,jstack)