文章目录
一文总结JVM
java类加载过程
类从被加载到JVM到卸载为止,整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段
类加载器分类
-
启动类加载器/Bootstrap ClassLoader
在HotSpot虚拟机中,Bootstrap ClassLoader用C++语言编写并嵌入JVM内部,主要负载加载JAVA_HOME/lib目录中的所有类,或者加载由选项-Xbootcalsspath指定的路径下的类; -
拓展类加载器/ExtClassLoader
负载加载JAVA_HOME/lib/ext目录中的所有类型,或者由参数-Xbootclasspath指定路径中的所有类型; -
应用程序类加载器/AppClassLoader
负责加载用户类路径ClassPath下的所有类型,一般情况下为程序的默认类加载器;
ExtClassLoader和AppClassLoader的父类都是ClassLoader
-
自定义加载器
Java虚拟机规范将所有继承抽象类java.lang.ClassLoader的类加载器,定义为自定义类加载器;
双亲委派
-
双亲委派模型
-
双亲委派过程
当一个类加载器收到类加载任务时,立即将任务委派给它的父类(并不是java含义中的父类
)加载器去执行,直至委派给最顶层的启动类加载器为止。如果父类加载器无法加载委派给它的类时,将类加载任务退回给它的下一级加载器去执行;
除了启动类加载器以外,每个类加载器拥有一个父类加载器,用户的自定义类加载器的父类加载器是AppClassLoader; -
双亲委派优点
- 避免类的重复加载
双亲委派模型可以保证全限名指定的类,只被加载一次; - 沙箱安全机制
自己写的java.lang.String.class类不会被加载,这样便可以防止核心API库被随意篡改
双亲委派模型不具有强制性约束,是Java设计者推荐的类加载器实现方式;
打破双亲委派机制
- 打破双亲委派机制
打破双亲委派
JVM内存模型
- jvm的主要组成部分
jvm主要由类装载子系统、执行引擎,运行时数据区组成
- 栈
可以理解为由很多个线程栈所组成的内存区域,JVM会给每个单独的线程开辟一个独立的栈空间 - 栈帧
栈帧用于存储局部变量、操作数栈,动态链接,方法出口,一个方法对应特定的栈帧内存区域,这也是为什么递归调用场景,如果没有出口将会导致栈内存溢出 - 本地方法栈
带有native关键字的方法的方法栈 - 堆
堆分为年轻代(edem区,S0,S1),老年代 - 垃圾回收
minor GC,full GC - 元空间
存放类信息
常用命令
jps
查看进程
jmap
jmap -histo
- jmap -histo 25124
查看25124进程对应的内存信息,实例个数和所占用的内存num #instances #bytes class name ---------------------------------------------- 1: 232314 52764168 [B 2: 360321 47344648 [C 3: 25177 31904624 [I 4: 165861 3980664 java.lang.String 5: 38558 3393104 java.lang.reflect.Method 6: 50254 3046304 [Ljava.lang.Object; 7: 105103 2238208 [Ljava.lang.Class; 8: 18531 1476256 [S 9: 16513 1343104 [Ljava.util.HashMap$Node; 10: 27392 1314816 java.util.HashMap 11: 34464 1102848 java.util.HashMap$Node 12: 9614 1075616 java.lang.Class 13: 29226 935232 java.util.concurrent.ConcurrentHashMap$Node 14: 38277 918648 java.lang.StringBuilder 15: 18214 728560 java.util.LinkedHashMap$Entry 16: 18896 604672 java.lang.ref.WeakReference 17: 9621 538776 java.util.LinkedHashMap 18: 10492 450368 [Ljava.lang.reflect.Method; 19: 6193 445896 java.lang.reflect.Field 20: 231 379696 [Ljava.util.concurrent.ConcurrentHashMap$Node; 21: 22519 360304 java.util.HashSet 22: 14480 347520 java.util.ArrayList 23: 10298 329536 java.util.ArrayList$Itr 24: 9050 309152 [Ljava.lang.String; 25: 6996 279840 java.lang.ref.SoftReference 26: 11947 276592 [Ljava.lang.reflect.Type;
jmap -heap
-
jmap -heap 25124
查看堆信息Attaching to process ID 25124, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.152-b16 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 2116026368 (2018.0MB) NewSize = 44564480 (42.5MB) MaxNewSize = 705167360 (672.5MB) OldSize = 89653248 (85.5MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 246939648 (235.5MB) used = 136945832 (130.60172271728516MB) free = 109993816 (104.89827728271484MB) 55.45720709863489% used From Space: capacity = 10485760 (10.0MB) used = 10297888 (9.820831298828125MB) free = 187872 (0.179168701171875MB) 98.20831298828125% used To Space: capacity = 16252928 (15.5MB) used = 0 (0.0MB) free = 16252928 (15.5MB) 0.0% used PS Old Generation capacity = 94371840 (90.0MB) used = 23666896 (22.570510864257812MB) free = 70704944 (67.42948913574219MB) 25.078345404730904% used 24858 interned Strings occupying 3011960 bytes.
jmap -dump:format=b,file=example.hprof 25124
-
dump堆内存
jmap -dump:format=b,file=example.hprof 25124
-XX:+HeapDumpOnOutOfMemoryError //设置内存溢出自动导出dump文件
-XX:HeapDumpPath=d:example.hprof //设置路径
-
dump文件的查看
cmd->jvisualvm->文件->装入->选择文件
-
效果
jstack
- jstack
打印进程中正在运行的线程的信息
分析死锁
jstack 6736 >deadlock.txt
2021-04-28 13:31:29
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.152-b16 mixed mode):
"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x0000000002f87000 nid=0x6b20 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Thread-1" #12 prio=5 os_prio=0 tid=0x00000000197af800 nid=0x7300 waiting for monitor entry [0x000000001a50f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.ljb.springboot.DeadLockThread.run(DeadLock.java:48)
- waiting to lock <0x00000000d6343f08> (a java.lang.Object)
- locked <0x00000000d6343f18> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
"Thread-0" #11 prio=5 os_prio=0 tid=0x00000000197bb000 nid=0x72e0 waiting for monitor entry [0x000000001a40e000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.ljb.springboot.DeadLockThread.run(DeadLock.java:35)
- waiting to lock <0x00000000d6343f18> (a java.lang.Object)
- locked <0x00000000d6343f08> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x0000000019751000 nid=0x3e60 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x00000000196b9800 nid=0x62d0 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x00000000192c3000 nid=0x3f20 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x00000000195cf000 nid=0x72b4 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x0000000019640000 nid=0xaa4 runnable [0x0000000019e0e000]
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 <0x00000000d63abc60> (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 <0x00000000d63abc60> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:47)
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000018f52800 nid=0x6d58 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000017bb7000 nid=0x610c runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000017b90000 nid=0x3374 in Object.wait() [0x0000000018f0e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d5f88ec8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x00000000d5f88ec8> (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)
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000017b68800 nid=0x6be8 in Object.wait() [0x0000000018e0f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d5f86b68> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000000d5f86b68> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=2 tid=0x0000000017b67800 nid=0x5384 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002f9d000 nid=0x6d1c runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002f9e800 nid=0x3b4c runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002fa0000 nid=0x4f08 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002fa1800 nid=0x68f4 runnable
"VM Periodic Task Thread" os_prio=2 tid=0x00000000197a7800 nid=0x5408 waiting on condition
JNI global references: 13
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x0000000017b6e168 (object 0x00000000d6343f08, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x0000000017b6f608 (object 0x00000000d6343f18, a java.lang.Object),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at com.ljb.springboot.DeadLockThread.run(DeadLock.java:48)
- waiting to lock <0x00000000d6343f08> (a java.lang.Object)
- locked <0x00000000d6343f18> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
"Thread-0":
at com.ljb.springboot.DeadLockThread.run(DeadLock.java:35)
- waiting to lock <0x00000000d6343f18> (a java.lang.Object)
- locked <0x00000000d6343f08> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
cpu使用率飙升原因分析
top->top -p ->shift+h->jstack
jinfo
jinfo
jinfo -flags
jstat
jstat -gc 29560
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
512.0 512.0 0.0 0.0 24064.0 16363.7 87552.0 1166.5 4864.0 3356.5 512.0 350.2 528 0.297 0 0.000 0.297