本文主要研究一下jvm的CompressedClassSpace
默认是开启
/ # jcmd 1 GC.heap_info 1: Shenandoah Heap 524288K total, 144896K committed, 77232K used 2048 x 256K regions Status: not cancelled Reserved region: - [0x00000000e0000000, 0x0000000100000000) Metaspace used 45675K, capacity 46867K, committed 47104K, reserved 1091584K class space used 5406K, capacity 5838K, committed 5888K, reserved 1048576K
可以看到整个metaspace使用了45675K,其中class space使用了5406K,而Metaspace area (excluding the Compressed Class Space)使用了45675K-5406K=40269K;整个metaspace的reserved大小为1091584K,其中class space的reserved大小为1048576K
/ # jcmd 1 VM.native_memory 1: Native Memory Tracking: Total: reserved=2224403KB, committed=238187KB - Java Heap (reserved=524288KB, committed=144896KB) (mmap: reserved=524288KB, committed=144896KB) - Class (reserved=1092940KB, committed=48460KB) (classes #8563) ( instance classes #7988, array classes #575) (malloc=1356KB #20589) (mmap: reserved=1091584KB, committed=47104KB) ( Metadata: ) ( reserved=43008KB, committed=41216KB) ( used=40286KB) ( free=930KB) ( waste=0KB =0.00%) ( Class space:) ( reserved=1048576KB, committed=5888KB) ( used=5407KB) ( free=481KB) ( waste=0KB =0.00%) - Thread (reserved=37130KB, committed=2846KB) (thread #36) (stack: reserved=36961KB, committed=2676KB) (malloc=127KB #189) (arena=42KB #70) - Code (reserved=529360KB, committed=15420KB) (malloc=968KB #4745) (mmap: reserved=528392KB, committed=14452KB) - GC (reserved=21844KB, committed=7724KB) (malloc=5460KB #9644) (mmap: reserved=16384KB, committed=2264KB) - Compiler (reserved=165KB, committed=165KB) (malloc=34KB #455) (arena=131KB #5) - Internal (reserved=3758KB, committed=3758KB) (malloc=1710KB #6582) (mmap: reserved=2048KB, committed=2048KB) - Other (reserved=32KB, committed=32KB) (malloc=32KB #3) - Symbol (reserved=10277KB, committed=10277KB) (malloc=7456KB #225421) (arena=2821KB #1) - Native Memory Tracking (reserved=4235KB, committed=4235KB) (malloc=10KB #126) (tracking overhead=4225KB) - Arena Chunk (reserved=176KB, committed=176KB) (malloc=176KB) - Logging (reserved=7KB, committed=7KB) (malloc=7KB #264) - Arguments (reserved=18KB, committed=18KB) (malloc=18KB #500) - Module (reserved=165KB, committed=165KB) (malloc=165KB #1708) - Safepoint (reserved=4KB, committed=4KB) (mmap: reserved=4KB, committed=4KB) - Unknown (reserved=4KB, committed=4KB) (mmap: reserved=4KB, committed=4KB)
可以看到class部分,reserved大小为1092940KB,其中Metadata的reserved大小为43008KB,Class space的reserved大小为1048576KB;其中Metadata使用了40286KB,而Class space使用了5407KB
@GetMapping("/meta") public Object getMetaspaceSize(){ return ManagementFactory.getPlatformMXBeans(MemoryPoolMXBean.class) .stream() .filter(e -> MemoryType.NON_HEAP == e.getType()) .filter(e -> e.getName().equals("Metaspace") || e.getName().equals("Compressed Class Space")) .map(e -> "name:"+e.getName()+",info:"+e.getUsage()) .collect(Collectors.toList()); }
输出如下:
/ # curl -i localhost:8080/memory/meta HTTP/1.1 200 Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Date: Sun, 31 Mar 2019 03:06:55 GMT ["name:Metaspace,info:init = 0(0K) used = 46236784(45153K) committed = 47710208(46592K) max = -1(-1K)","name:Compressed Class Space,info:init = 0(0K) used = 5482736(5354K) committed = 6029312(5888K) max = 1073741824(1048576K)"]
这里可以看到Metaspace总共使用了45153K,其中Compressed Class Space部分使用了5354K,而Metaspace area (excluding the Compressed Class Space)使用了45153K-5354K=39799K;而这里显示的Metaspace的max为-1,其中Compressed Class Space部分max值为1048576K即1G
/ # curl -i "http://localhost:8080/actuator/metrics/jvm.memory.used?tag=area:nonheap" HTTP/1.1 200 Content-Disposition: inline;filename=f.txt Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8 Transfer-Encoding: chunked Date: Sun, 31 Mar 2019 02:52:51 GMT {"name":"jvm.memory.used","description":"The amount of used memory","baseUnit":"bytes","measurements":[{"statistic":"VALUE","value":6.4449464E7}],"availableTags":[{"tag":"id","values":["CodeHeap 'non-profiled nmethods'","CodeHeap 'profiled nmethods'","Compressed Class Space","Metaspace","CodeHeap 'non-nmethods'"]}]} / # curl -i "http://localhost:8080/actuator/metrics/jvm.memory.used?tag=area:nonheap&tag=id:Metaspace" HTTP/1.1 200 Content-Disposition: inline;filename=f.txt Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8 Transfer-Encoding: chunked Date: Sun, 31 Mar 2019 02:54:56 GMT {"name":"jvm.memory.used","description":"The amount of used memory","baseUnit":"bytes","measurements":[{"statistic":"VALUE","value":4.7468312E7}],"availableTags":[]} / # curl -i "http://localhost:8080/actuator/metrics/jvm.memory.used?tag=area:nonheap&tag=id:Compressed% 20Class%20Space" HTTP/1.1 200 Content-Disposition: inline;filename=f.txt Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8 Transfer-Encoding: chunked Date: Sun, 31 Mar 2019 02:55:18 GMT {"name":"jvm.memory.used","description":"The amount of used memory","baseUnit":"bytes","measurements":[{"statistic":"VALUE","value":5609952.0}],"availableTags":[]}
springboot使用micrometer,通过/actuator/metrics接口提供相关指标查询功能,其中Metaspace及Compressed Class Space在jvm.memory.used这个metric中
默认是开启
),则UseCompressedOops会使用32-bit的offset来代表java object的引用,而UseCompressedClassPointers则使用32-bit的offset来代表64-bit进程中的class pointer;可以使用CompressedClassSpaceSize来设置这块的空间大小 查看CompressedClassSpace的内存使用情况有好几种方法:
Metaspace为总的部分,包含了class space,而Metaspace area (excluding the Compressed Class Space)需要自己计算即total-class space class为总的部分,包含了Metaspace area (excluding the Compressed Class Space)及Class Space JMX得到的Metaspace为总的部分,Metaspace area (excluding the Compressed Class Space)需要自己计算即total-class space