这里简单的回顾了一下JVM内存模型和GC回收器相关的知识点。由于画图的时候比较青睐Office的Visio,所以可能贴图不打清晰。
为什么写这篇文章呢,主要是懂了JVM内存模型,就可以在不自觉中写出优良代码,比如使用DirectByteBuffer,因为这个是在stack上分配的,栈帧弹出就消失了,还有就是Thread Local Allocation Buffer,也都是分配内存的时候,首先在栈中分配,分配不下才回去Heap分配。懂了GC垃圾回收,就可以明白java是如何管理内存的,这些可以帮助你认知整个Java世界,从类加载到消亡,全部关联起来,打通任督二脉,提升境界,然后羽化成仙。。。好了废话不多说,直接上图:
大概就是这样,讲的很模糊,做实验也只是在自己的电脑上,没有在生产环境JVM调优过(虽然有一次改过Xmx,就这么一个参数)。附上Visio原图,版本是Visio 2016 Pro
实验结果:
"C:\Program Files\Java\jdk-11.0.7\bin\java.exe" -Dport=8000 -verbose:gc -Xms2M -Xmx4M "-Xlog:gc*" "-Xlog:age*" -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:-UseZGC "-javaagent:rpc.App
[0.013s][info][gc,heap] Heap region size: 1M // 分区大小1m
[0.014s][info][gc ] Using G1 //使用G1
[0.014s][info][gc,heap,coops] Heap address: 0x00000000ffc00000, size: 4 MB, Compressed Oops mode: 32-bit
[0.126s][info][gc,start ] GC(0) Pause Young (Normal) (G1 Evacuation Pause)
[0.126s][info][gc,task ] GC(0) Using 2 workers of 8 for evacuation//八个线程用了两个做GC
[0.127s][info][gc,phases ] GC(0) Pre Evacuate Collection Set: 0.0ms// 看起来有四个phases,但是没有详细的过程
[0.127s][info][gc,phases ] GC(0) Evacuate Collection Set: 1.0ms
[0.127s][info][gc,phases ] GC(0) Post Evacuate Collection Set: 0.1ms
[0.127s][info][gc,phases ] GC(0) Other: 0.2ms
[0.127s][info][gc,heap ] GC(0) Eden regions: 1->0(1)// 这是GC结果,Eden区
[0.127s][info][gc,heap ] GC(0) Survivor regions: 0->1(1)// servivor区
[0.127s][info][gc,heap ] GC(0) Old regions: 0->0//old 区
[0.127s][info][gc,heap ] GC(0) Humongous regions: 0->0 // 巨型对象region区
[0.127s][info][gc,metaspace ] GC(0) Metaspace: 4665K->4665K(1056768K)//元空间
[0.127s][info][gc ] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 1M->0M(2M) 1.474ms//总共GC花了1.474毫秒
[0.127s][info][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.00s//cpu负载
[0.171s][info][gc,start ] GC(1) Pause Young (Normal) (G1 Evacuation Pause)//下一轮GC
[0.171s][info][gc,task ] GC(1) Using 2 workers of 8 for evacuation
[0.172s][info][gc,phases ] GC(1) Pre Evacuate Collection Set: 0.0ms
[0.172s][info][gc,phases ] GC(1) Evacuate Collection Set: 1.3ms
[0.172s][info][gc,phases ] GC(1) Post Evacuate Collection Set: 0.1ms
[0.172s][info][gc,phases ] GC(1) Other: 0.1ms
[0.172s][info][gc,heap ] GC(1) Eden regions: 1->0(1)
[0.172s][info][gc,heap ] GC(1) Survivor regions: 1->1(1)
[0.172s][info][gc,heap ] GC(1) Old regions: 0->1
[0.172s][info][gc,heap ] GC(1) Humongous regions: 0->0
[0.172s][info][gc,metaspace ] GC(1) Metaspace: 5842K->5842K(1056768K)
[0.172s][info][gc ] GC(1) Pause Young (Normal) (G1 Evacuation Pause) 1M->1M(4M) 1.501ms
[0.172s][info][gc,cpu ] GC(1) User=0.00s Sys=0.00s Real=0.00s
PrintDCDetails过期了,要使用Xlog:gc*,这个是jdk11.0.4,使用的是G1垃圾回收器,region大小是1M
本来想在jdk11.04看ZGC效果的,但是开不出来,又试了jdk11.0.7,还是一样:
"C:\Program Files\Java\jdk-11.0.7\bin\java.exe" -Dport=8000 -verbose:gc "-Xlog:gc*" -XX:-UseG1GC -server -XX:+UnlockExperimentalVMOptions -XX:+UseZGC "-Xlog:age*,gc*=info:file=gc-%t.log:time,tid,tags:filecount=3,filesize=20m" "-javaagent:rpc.App
Error occurred during initialization of VM
Option -XX:+UseZGC not supported
Process finished with exit code 1
这里我还手动关闭G1,开启ZGC,但是还是不行。换成jdk14,就可以了:
"C:\Program Files\Java\jdk-14.0.1\bin\java.exe" -Dport=8000 -verbose:gc "-Xlog:gc*" "-Xlog:age*" -XX:-UseG1GC -Xms20M -Xmx21M -XX:+UnlockExperimentalVMOptions -XX:+UseZGC "-javaagent:rpc.App
[0.013s][info][gc,init] Initializing The Z Garbage Collector // ZGC
[0.013s][info][gc,init] Version: 14.0.1+7 (release) //JDK verison
[0.013s][info][gc,init] NUMA Support: Disabled
[0.013s][info][gc,init] CPUs: 8 total, 8 available
[0.013s][info][gc,init] Memory: 8076M
[0.013s][info][gc,init] Large Page Support: Disabled
[0.013s][info][gc,init] Medium Page Size: N/A
[0.013s][info][gc,init] Workers: 1 parallel, 1 concurrent // 一个并发,一个并行
[0.013s][info][gc,init] Address Space Type: Contiguous/Unrestricted/Complete
[0.013s][info][gc,init] Address Space Size: 352M x 3 = 1056M
[0.013s][info][gc,init] Min Capacity: 20M
[0.013s][info][gc,init] Initial Capacity: 20M // 通过参数-Xms20M
[0.013s][info][gc,init] Max Capacity: 22M // 这里我设置的是21,但是不知道为啥变成22了
[0.013s][info][gc,init] Max Reserve: 2M // 2m保留区
[0.013s][info][gc,init] Pre-touch: Disabled
[0.014s][info][gc,init] Uncommit: Enabled, Delay: 300s
[0.029s][info][gc,init] Runtime Workers: 1 parallel
[0.029s][info][gc ] Using The Z Garbage Collector // ZGC
[0.179s][info][gc,start] GC(0) Garbage Collection (Warmup)// 开始GC了,预热
[0.180s][info][gc,phases] GC(0) Pause Mark Start 0.407ms// STW标记
[0.183s][info][gc,phases] GC(0) Concurrent Mark 2.756ms
[0.183s][info][gc,phases] GC(0) Pause Mark End 0.027ms// STW标记结束
[0.183s][info][gc,phases] GC(0) Concurrent Process Non-Strong References 0.410ms
[0.183s][info][gc,phases] GC(0) Concurrent Reset Relocation Set 0.001ms
[0.193s][info][gc,phases] GC(0) Concurrent Select Relocation Set 9.957ms
[0.194s][info][gc,phases] GC(0) Pause Relocate Start 0.342ms
[0.196s][info][gc,phases] GC(0) Concurrent Relocate 1.791ms // 到这里应该是在处理各种引用,染色
[0.196s][info][gc,load ] GC(0) Load: 0.00/0.00/0.00 // 负载情况
[0.196s][info][gc,mmu ] GC(0) MMU: 2ms/79.7%, 5ms/91.3%, 10ms/95.7%, 20ms/96.1%, 50ms/98.4%, 100ms/99.2%
[0.196s][info][gc,marking] GC(0) Mark: 1 stripe(s), 2 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s)
[0.196s][info][gc,reloc ] GC(0) Relocation: Successful, 0M relocated//这里是染色完成,应该是
[0.196s][info][gc,nmethod] GC(0) NMethods: 173 registered, 0 unregistered
[0.196s][info][gc,metaspace] GC(0) Metaspace: 4M used, 4M capacity, 5M committed, 8M reserved
[0.196s][info][gc,ref ] GC(0) Soft: 36 encountered, 0 discovered, 0 enqueued// 软引用
[0.196s][info][gc,ref ] GC(0) Weak: 99 encountered, 92 discovered, 17 enqueued//弱引用
[0.196s][info][gc,ref ] GC(0) Final: 0 encountered, 0 discovered, 0 enqueued//final引用
[0.196s][info][gc,ref ] GC(0) Phantom: 14 encountered, 14 discovered, 13 enqueued//虚引用
[0.196s][info][gc,heap ] GC(0) Min Capacity: 20M(91%)
[0.196s][info][gc,heap ] GC(0) Max Capacity: 22M(100%)
[0.196s][info][gc,heap ] GC(0) Soft Max Capacity: 22M(100%)
[0.196s][info][gc,heap ] GC(0) Mark Start Mark End Relocate Start Relocate End High Low
[0.196s][info][gc,heap ] GC(0) Capacity: 20M (91%) 20M (91%) 20M (91%) 20M (91%) 20M (91%) 20M (91%)
[0.196s][info][gc,heap ] GC(0) Reserve: 2M (9%) 2M (9%) 2M (9%) 2M (9%) 2M (9%) 2M (9%)
[0.196s][info][gc,heap ] GC(0) Free: 16M (73%) 14M (64%) 14M (64%) 16M (73%) 16M (73%) 12M (55%)
[0.196s][info][gc,heap ] GC(0) Used: 4M (18%) 6M (27%) 6M (27%) 4M (18%) 8M (36%) 4M (18%)
[0.196s][info][gc,heap ] GC(0) Live: - 0M (4%) 0M (4%) 0M (4%) - -
[0.196s][info][gc,heap ] GC(0) Allocated: - 2M (9%) 2M (9%) 4M (18%) - -
[0.196s][info][gc,heap ] GC(0) Garbage: - 3M (14%) 3M (14%) 1M (5%) - -
[0.196s][info][gc,heap ] GC(0) Reclaimed: - - 0M (0%) 2M (9%) - -
[0.196s][info][gc ] GC(0) Garbage Collection (Warmup) 4M(18%)->4M(18%)//GC完成,一点儿都没回收。
[0.279s][info][gc,start ] GC(1) Garbage Collection (Warmup)// 下一次GC开始啦
[0.280s][info][gc,phases ] GC(1) Pause Mark Start 0.386ms
[0.284s][info][gc,phases ] GC(1) Concurrent Mark 4.520ms
[0.284s][info][gc,phases ] GC(1) Pause Mark End 0.025ms
[0.285s][info][gc,phases ] GC(1) Concurrent Process Non-Strong References 0.659ms
[0.285s][info][gc,phases ] GC(1) Concurrent Reset Relocation Set 0.063ms
[0.288s][info][gc,phases ] GC(1) Concurrent Select Relocation Set 2.950ms
[0.288s][info][gc,phases ] GC(1) Pause Relocate Start 0.192ms
[0.292s][info][gc,phases ] GC(1) Concurrent Relocate 3.723ms
[0.292s][info][gc,load ] GC(1) Load: 0.00/0.00/0.00
[0.292s][info][gc,mmu ] GC(1) MMU: 2ms/79.7%, 5ms/91.3%, 10ms/94.0%, 20ms/96.1%, 50ms/98.4%, 100ms/99.0%
[0.292s][info][gc,marking ] GC(1) Mark: 1 stripe(s), 2 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s)
[0.292s][info][gc,reloc ] GC(1) Relocation: Successful, 1M relocated
[0.292s][info][gc,nmethod ] GC(1) NMethods: 239 registered, 0 unregistered
[0.292s][info][gc,metaspace] GC(1) Metaspace: 5M used, 5M capacity, 6M committed, 8M reserved
[0.292s][info][gc,ref ] GC(1) Soft: 37 encountered, 0 discovered, 0 enqueued
[0.292s][info][gc,ref ] GC(1) Weak: 89 encountered, 78 discovered, 2 enqueued
[0.292s][info][gc,ref ] GC(1) Final: 0 encountered, 0 discovered, 0 enqueued
[0.292s][info][gc,ref ] GC(1) Phantom: 56 encountered, 44 discovered, 1 enqueued
[0.292s][info][gc,heap ] GC(1) Min Capacity: 20M(91%)
[0.292s][info][gc,heap ] GC(1) Max Capacity: 22M(100%)
[0.292s][info][gc,heap ] GC(1) Soft Max Capacity: 22M(100%)
[0.292s][info][gc,heap ] GC(1) Mark Start Mark End Relocate Start Relocate End High Low
[0.292s][info][gc,heap ] GC(1) Capacity: 20M (91%) 20M (91%) 20M (91%) 20M (91%) 20M (91%) 20M (91%)
[0.292s][info][gc,heap ] GC(1) Reserve: 2M (9%) 2M (9%) 2M (9%) 2M (9%) 2M (9%) 2M (9%)
[0.292s][info][gc,heap ] GC(1) Free: 12M (55%) 8M (36%) 8M (36%) 10M (45%) 12M (55%) 6M (27%)
[0.292s][info][gc,heap ] GC(1) Used: 8M (36%) 12M (55%) 12M (55%) 10M (45%) 14M (64%) 8M (36%)
[0.292s][info][gc,heap ] GC(1) Live: - 4M (20%) 4M (20%) 4M (20%) - -
[0.292s][info][gc,heap ] GC(1) Allocated: - 4M (18%) 4M (18%) 6M (27%) - -
[0.292s][info][gc,heap ] GC(1) Garbage: - 3M (16%) 3M (16%) 1M (7%) - -
[0.292s][info][gc,heap ] GC(1) Reclaimed: - - 0M (0%) 2M (9%) - -
[0.292s][info][gc ] GC(1) Garbage Collection (Warmup) 8M(36%)->10M(45%)
[0.379s][info][gc,start ] GC(2) Garbage Collection (Warmup)
[0.380s][info][gc,phases ] GC(2) Pause Mark Start 0.680ms
[0.386s][info][gc,phases ] GC(2) Concurrent Mark 6.595ms
[0.386s][info][gc,phases ] GC(2) Pause Mark End 0.029ms
[0.387s][info][gc,phases ] GC(2) Concurrent Process Non-Strong References 0.945ms
[0.387s][info][gc,phases ] GC(2) Concurrent Reset Relocation Set 0.003ms
[0.390s][info][gc,phases ] GC(2) Concurrent Select Relocation Set 2.244ms
[0.390s][info][gc,phases ] GC(2) Pause Relocate Start 0.228ms
[0.393s][info][gc,phases ] GC(2) Concurrent Relocate 2.079ms
[0.393s][info][gc,load ] GC(2) Load: 0.00/0.00/0.00
[0.393s][info][gc,mmu ] GC(2) MMU: 2ms/66.0%, 5ms/86.4%, 10ms/92.9%, 20ms/95.3%, 50ms/98.1%, 100ms/99.0%
[0.393s][info][gc,marking ] GC(2) Mark: 1 stripe(s), 2 proactive flush(es), 1 terminate flush(es), 0 completion(s), 0 continuation(s)
[0.393s][info][gc,reloc ] GC(2) Relocation: Successful, 1M relocated
[0.393s][info][gc,nmethod ] GC(2) NMethods: 373 registered, 0 unregistered
[0.393s][info][gc,metaspace] GC(2) Metaspace: 7M used, 7M capacity, 7M committed, 8M reserved
[0.393s][info][gc,ref ] GC(2) Soft: 95 encountered, 0 discovered, 0 enqueued
[0.393s][info][gc,ref ] GC(2) Weak: 220 encountered, 185 discovered, 30 enqueued
[0.393s][info][gc,ref ] GC(2) Final: 0 encountered, 0 discovered, 0 enqueued
[0.393s][info][gc,ref ] GC(2) Phantom: 88 encountered, 70 discovered, 5 enqueued
[0.393s][info][gc,heap ] GC(2) Min Capacity: 20M(91%)
[0.393s][info][gc,heap ] GC(2) Max Capacity: 22M(100%)
[0.393s][info][gc,heap ] GC(2) Soft Max Capacity: 22M(100%)
[0.393s][info][gc,heap ] GC(2) Mark Start Mark End Relocate Start Relocate End High Low
[0.393s][info][gc,heap ] GC(2) Capacity: 20M (91%) 20M (91%) 20M (91%) 20M (91%) 20M (91%) 20M (91%)
[0.393s][info][gc,heap ] GC(2) Reserve: 2M (9%) 2M (9%) 2M (9%) 2M (9%) 2M (9%) 2M (9%)
[0.393s][info][gc,heap ] GC(2) Free: 8M (36%) 6M (27%) 8M (36%) 12M (55%) 12M (55%) 6M (27%)
[0.393s][info][gc,heap ] GC(2) Used: 12M (55%) 14M (64%) 12M (55%) 8M (36%) 14M (64%) 8M (36%)
[0.393s][info][gc,heap ] GC(2) Live: - 4M (21%) 4M (21%) 4M (21%) - -
[0.393s][info][gc,heap ] GC(2) Allocated: - 2M (9%) 2M (9%) 4M (18%) - -
[0.393s][info][gc,heap ] GC(2) Garbage: - 7M (34%) 5M (25%) 1M (7%) - -
[0.393s][info][gc,heap ] GC(2) Reclaimed: - - 2M (9%) 6M (27%) - -
[0.393s][info][gc ] GC(2) Garbage Collection (Warmup) 12M(55%)->8M(36%)
Process finished with exit code -1