专栏首页码匠的流水账聊聊jvm的CompressedClassSpace
原创

聊聊jvm的CompressedClassSpace

本文主要研究一下jvm的CompressedClassSpace

CompressedClassSpace

  • java8移除了permanent generation,然后class metadata存储在native memory中,其大小默认是不受限的,可以通过-XX:MaxMetaspaceSize来限制
  • 如果开启了-XX:+UseCompressedOops及-XX:+UseCompressedClassesPointers(默认是开启),则UseCompressedOops会使用32-bit的offset来代表java object的引用,而UseCompressedClassPointers则使用32-bit的offset来代表64-bit进程中的class pointer;可以使用CompressedClassSpaceSize来设置这块的空间大小
  • 如果开启了指针压缩,则CompressedClassSpace分配在MaxMetaspaceSize里头,即MaxMetaspaceSize=Compressed Class Space Size + Metaspace area (excluding the Compressed Class Space) Size

查看CompressedClassSpace大小

jcmd pid GC.heap_info

/ # 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 pid VM.native_memory

/ # 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

jmx查看

    @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

spring boot应用查看

/ # 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中 它是基于MemoryPoolMXBean来实现的,具体详见micrometer-core-1.1.3-sources.jar!/io/micrometer/core/instrument/binder/jvm/JvmMemoryMetrics.java

小结

  • java8移除了permanent generation,然后class metadata存储在native memory中,其大小默认是不受限的,可以通过-XX:MaxMetaspaceSize来限制;如果开启了-XX:+UseCompressedOops及-XX:+UseCompressedClassesPointers(默认是开启),则UseCompressedOops会使用32-bit的offset来代表java object的引用,而UseCompressedClassPointers则使用32-bit的offset来代表64-bit进程中的class pointer;可以使用CompressedClassSpaceSize来设置这块的空间大小
  • 开启了指针压缩,则CompressedClassSpace分配在MaxMetaspaceSize里头,即MaxMetaspaceSize=Compressed Class Space Size + Metaspace area (excluding the Compressed Class Space) Size
  • 查看CompressedClassSpace的内存使用情况有好几种方法:
    • jcmd pid GC.heap_info(Metaspace为总的部分,包含了class space,而Metaspace area (excluding the Compressed Class Space)需要自己计算即total-class space)
    • jcmd pid VM.native_memory(class为总的部分,包含了Metaspace area (excluding the Compressed Class Space)及Class Space)
    • 使用JMX来获取NON_HEAP类型中的name为Metaspace及Compressed Class Space的MemoryPoolMXBean可以得到Metaspace及Compressed Class Space的使用情况(JMX得到的Metaspace为总的部分,而Metaspace area (excluding the Compressed Class Space)需要自己计算即total-class space)
    • 如果是springboot应用,它使用micrometer,通过/actuator/metrics接口提供相关指标查询功能,其中Metaspace及Compressed Class Space在jvm.memory.used这个metric中

doc

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊jvm的-XX:MaxDirectMemorySize

    code4it
  • 聊聊jvm的Code Cache

    JVM生成的native code存放的内存空间称之为Code Cache;JIT编译、JNI等都会编译代码到native code,其中JIT生成的nativ...

    code4it
  • 聊聊jvm的Stack Memory

    code4it
  • 聊一聊 JVM 的 GC

    JVM 中的 GC 在技术博客中应该算是个老生常谈的话题,网络上也存在着许多质量参差不齐的文章,可以看出来大都是“复制粘贴”的风格。在写这篇文章的时候,我问了问...

    壹言
  • 聊聊jvm的PermGen与Metaspace

    对于垃圾收集算法来说,分代回收是高级算法之一。对象按照生成时间进行分代,刚刚生成不久的年轻对象划为新生代(Young gen-eration),而存活了较长时间...

    code4it
  • 聊聊jvm的StringTable及SymbolTable

    code4it
  • 聊聊skywalking的jvm-receiver-plugin

    skywalking-6.6.0/oap-server/server-receiver-plugin/skywalking-jvm-receiver-plugi...

    code4it
  • 聊聊skywalking的jvm-receiver-plugin

    skywalking-6.6.0/oap-server/server-receiver-plugin/skywalking-jvm-receiver-plugi...

    code4it
  • JAVA-聊聊JVM的年轻代

    jmap -histo:live pid | less 可以观察heap中所有对象的情况(heap中所有生存的对象的情况)

    用户2825413
  • 聊聊 Java 的几把 JVM 级锁

    在计算机行业有一个定律叫"摩尔定律",在此定律下,计算机的性能突飞猛进,而且价格也随之越来越便宜, CPU 从单核到了多核,缓存性能也得到了很大提升,尤其是多核...

    用户1516716
  • 面试官:聊聊JVM吧?

    作者从类加载子系统, 运行时数据区, 执行引擎, 垃圾回收机制, 性能优化, 高效并发这6个方向详细的介绍了JVM底层的运行机制原理,以及整理了一些面试...

    开源君
  • 面试官:聊聊JVM吧?

    作者从类加载子系统, 运行时数据区, 执行引擎, 垃圾回收机制, 性能优化, 高效并发这6个方向详细的介绍了JVM底层的运行机制原理,以及整理了一些面试...

    开源君
  • 聊聊JVM中的垃圾回收(GC)

    Java相对于C/C++语言来说,最明显的特点在于Java引入了自动垃圾回收。垃圾回收(Garbage Collection简称GC)可以使程序员不在需要关心J...

    java技术爱好者
  • 聊聊flink taskmanager的jvm-exit-on-oom配置

    本文主要研究一下flink taskmanager的jvm-exit-on-oom配置

    code4it
  • 面试必问|聊聊JVM性能调优?

    对于工作3年左右的Java程序员来说,在面试大厂的过程中,面试官可能不会太关注你做了多少个项目、你的CRUD水平如何。更多的是关注你对某项技术点的理解深度,所以...

    用户1263954
  • 面试必问|聊聊JVM性能调优?

    之前在写【字节码编程】系列时,不少小伙伴希望我能写一些关于面试的知识,出一些相对来说有一点技术深度的面试知识点。

    冰河
  • 跟大家聊聊 JVM 中的双亲委派机制

    JVM对字节码文件采用的是按需加载方法,什么时候使用这个类才会将它的字节码加载到内存生成Class对象呢?我们用案例测试一下什么是双亲委派机制。

    程序员小强
  • 今天我们来聊聊JVM类加载机制

    说到jvm 那么不得不提类的加载过程.我们先来了解下类是如何被一步一步加载到jvm的

    Java宝典
  • 大白话谈JVM的类加载机制

    我们很多小伙伴平时都是做JAVA开发的,那么作为一名合格的工程师,你是否有仔细的思考过JVM的运行原理呢。

    HUC思梦

扫码关注云+社区

领取腾讯云代金券