首页 > 系统相关 >Java 内存分区之什么是 CCS区 Compressed Class Space 类压缩空间

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

时间:2022-11-15 13:58:17浏览次数:70  
标签:Java Compressed Space 压缩 CCS XX Klass Class 指针

https://blog.csdn.net/qq_27093465/article/details/106760961

 

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 

_________________________________________________________________________________________________________

 

 
链接:https://www.zhihu.com/question/268392125/answer/1271619241 

JVM 有个功能是 CompressedOops ,目的是为了在 64bit 机器上使用 32bit 的原始对象指针(oop,ordinary object pointer,这里直接就当成指针概念理解就可以了,

不用关心啥是 ordinary)来节约成本(减少内存/带宽使用),提高性能(提高 Cache 命中率)。使用了这个压缩功能,每个对象中的 Klass* 字段就会被压缩成 32bit(不是所有的 oop 都会被压缩的),

总所周知 Klass* 指向的 Klass 在永久代(Java7 及之前)。但是在 Java8 及之后,永久代没了,有了一个 Metaspace,于是之前压缩指针 Klass* 指向的这块 Klass 区域有了一个名字 —— Compressed Class Space。

Compressed Class Space 是 Metaspace 的一部分,默认大小为 1G。所以其实 Compressed Class Space 这个名字取得很误导,压缩的并不是 Klass,而是 Klass*。

 

JVM 也为 compressed class pointers(Klass*)多了俩选项:

  • -XX:+UseCompressedClassPointers(压缩开关)
  • -XX:CompressedClassSpaceSize(Compressed Class Space 空间大小限制)。

-XX:+UseCompressedClassPointers 是需要 -XX:+UseCompressedOops 开启的,所以堆大小要是大于 32G,CompressedOops 自动关闭,CompressedClassPointers 也会关闭的,

关闭了就没有 Compressed Class Space 了,这块就是 Class Space 了。

-XX:CompressedClassSpaceSize 大小的设置也是有限制,因为压缩开关是受制于 32G,所以这个自然也是不能大于 32G,不过 hotspot 规定了这个参数不准大于 3G,

所以这个参数其实是不能大于 3G。

一般来说,平均一个 Klass 大小可以当成 1K 来算,默认的 1G 大小可以存储 100 万的 Klass。如果遇到了 `java.lang.OutOfMemoryError: Compressed class space`,

就是类太多了,需要结合具体情况去选择 JVM 调优还是 bug 排查。

 

标签:Java,Compressed,Space,压缩,CCS,XX,Klass,Class,指针
From: https://www.cnblogs.com/kelelipeng/p/16892172.html

相关文章

  • Java String类的isEmpty(),null的区别
    JavaString类的isEmpty(),null的区别一、理解isEmpty()完全等同于string.length()==0若String对象本身是NULL,即字符串对象的引用是空指针,那在使用String.isEmpty()方法......
  • kubernetes强制删除namespace
    1、执行命令删除namespace后一直显示Terminating,无法删除namespace[root@k8s-master1~]#kubectlgetnsNAMESTATUSAGEdefault......
  • 【Javaweb】六-servlet层
    AdminServlet.jap@WebServlet("/AdminServlet")publicclassAdminServletextendsHttpServlet{@Overrideprotectedvoidservice(HttpServletRequestrequ......
  • Javascript中字符串的instanceof String的结果
    如果是单纯的字符串赋给变量,虽然类型为string,但是instanceofString是false,并不是String对象,因为没有创建实例. 而这种new一个String实例则instanceof是属于String......
  • JAVA中的字符串加空格的实现方式
    一、问题描述我们现在输入了一个字符串,然后可能在一些情况下,我们需要将字符串中的每一个字符拿空格隔开,那么这种样式应该如何实现呢?二、实现思路我们直接将字符串变成数......
  • linux部署java环境
    一、进入到下载目录cd/usr/local/src二、下载Java下载地址JavaDownloads|Oracle下载完后执行下面这个命令然后选择到下载的文件后通过xshell上传上去或者通过......
  • UML中依赖泛化关联实现聚合组合的Java实现
     UML中依赖泛化关联实现聚合组合的Java实现在类图中,类与类之间的关系主要有一下几种: 泛化关系:publicclass Employee {}public class SaleEmployee extends Employee......
  • java中将word转换为html导入到ueditor编辑器中(解决图片问题,样式,非常完美)
    图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码目前限chrome浏览器使用首先以um-editor的二进制流保存为例:打开umeditor.js,找到UM.......
  • "等java转义
    在数据存入数据库之前应该会对数据进行转义为"等样式,如果包含有&就时经过两次加密的,所以转义的时候也需要经过两次转义。publicstaticvoidmain(String[]args){......
  • java变量
    1/*2//变量3//1.局部变量【存在指定的方法中】4//2.全局变量【在class中】5//3.类变量【带有指定字符static】6......