Java 内存分区之什么是 CCS区 Compressed Class Space 类压缩空间

        了解到什么是ccs区,一般都是实际执行了jstat -gc 之后,看Java堆的gc相关的几个分区的gc信息,前面的s0,s1,e区,o区,还好猜,研究过分区的,不难猜出来这个分区是啥意思,M区虽然不知道是Metaspace元空间,但是错把这个M区当成Method area 方法区,也说的过去。这个ccsc就不好说了。之前的看的文章都没人说这个区是啥。

 Java之jstat的用法:Java虚拟机 统计信息查看 工具

        不了解这几个简写单词是啥意思的,可以参考一下之前的这个jstat的文章,里面对每一列的title的简写都做了解释。

什么是 Compressed Class Space?
        在 64 位平台上,HotSpot 使用了两个压缩优化技术,Compressed Object Pointers (“CompressedOops”) 和 Compressed Class Pointers。
        压缩指针,指的是在 64 位的机器上,使用 32 位的指针来访问数据(堆中的对象或 Metaspace 中的元数据)的一种方式。
        这样有很多的好处,比如 32 位的指针占用更小的内存,可以更好地使用缓存,在有些平台,还可以使用到更多的寄存器。
        当然,在 64 位的机器中,最终还是需要一个 64 位的地址来访问数据的,所以这个 32 位的值是相对于一个基准地址的值。

        下面将描述 Compressed Class Pointers:

        每个 Java 对象,在它的头部,有一个引用指向 Metaspace 中的 Klass 结构。

         当使用了 compressed class pointers,这个引用是 32 位的值,为了找到真正的 64 位地址,需要加上一个 base 值:

         上面的内容应该很好理解,这项技术对 Klass 的分配带来的问题是:由于 32 位地址只能访问到 4G 的空间,所以最大只允许 4G 的 Klass 地址。这项限制也意味着,JVM 需要向 Metaspace 分配一个连续的地址空间。

        当从系统申请内存时,通过调用系统接口 malloc(3) 或 mmap(3),操作系统可能返回任意一个地址值,所以在 64位系统中,它并不能保证在 4G 的范围内。

        所以,我们只能用一个 mmap() 来申请一个区域单独用来存放 Klass 对象。我们需要提前知道这个区域的大小,而且不能超过 4G。显然,这种方式是不能扩展的,因为这个地址后面的内存可能是被占用的。

        只有 Klass 结构有这个限制,对于其他的 class metadata 没有这个必要: 因为只有 Klass 实例是通过 Java 对象 header 中的压缩指针访问的。其他的 metadata 都是通过 64 位的地址进行访问的,所以它们可以被放到任意的地址上。

        所以,我们决定将 Metaspace 分为两个区域:non-class part 和 class part。

  • class part:存放 Klass 对象,需要一个连续的不超过 4G 的内存
  • non-class part:包含其他的所有 metadata

class part 被称作 Compressed Class Space,这个名字会有点怪,因为 Klass 本身其实没有使用压缩技术,而是引用它们的指针被压缩了。

compressed class space 空间的大小,是通过 -XX:CompressedClassSpaceSize 指定的。

        我们需要提前知道自己需要多少内存,它的默认值是 1G。当然这个 1G 并不是真的使用了操作系统的 1G,而是虚拟地址映射。

开关: UseCompressedClassPointers, UseCompressedOops
-XX:+UseCompressedOops 允许对象指针压缩。

-XX:+UseCompressedClassPointers 允许类指针压缩。

它们默认都是开启的,可以手动关闭它们。

        如果不允许类指针压缩,那么将没有 compressed class space 这个空间,并且-XX:CompressedClassSpaceSize 这个参数无效。

        -XX:-UseCompressedClassPointers 需要搭配 -XX:+UseCompressedOops,但是反过来不是: 我们可以只压缩对象指针,不压缩类指针。

        这里面为什么这么规定我也不懂,但是从直觉上来说,压缩对象指针显然是比较重要的,能获得较大的收益。也许就是基于这种考量吧:你连对象指针都不压缩,类指针压缩不压缩又有什么关系呢?

注意,对象指针压缩要求堆小于 32G,所以如果堆大于等于 32G,那么对象指针压缩和类指针压缩都会被关闭。

参考:

深入理解堆外内存 Metaspace
 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值