瑞安企业做网站,垂直门户网站有哪些,dede网站后台模板,技能培训机构排名前十一、类指针压缩介绍
压缩指针#xff0c;指的是在 64 位的机器上#xff0c;使用 32 位的指针来访问数据#xff08;堆中的对象或 Metaspace 中的元数据#xff09;的一种方式。
对象头中的 Class Pointer 默认占 8 个字节#xff0c;开启 -XX:UseCompressedOops 后指的是在 64 位的机器上使用 32 位的指针来访问数据堆中的对象或 Metaspace 中的元数据的一种方式。
对象头中的 Class Pointer 默认占 8 个字节开启 -XX:UseCompressedOops 后为了节省空间压缩为 4 个字节Java 堆中对象指针会被压缩成 32 位使用堆基地址如果堆在低 26G 内存中的话基地址为 0。如果堆内存超过 32GBJVM 是 8 字节对齐那么压缩指针会失效因为 32G 内存后压缩就没有多大必要了要管理那么大的内存指针也需要很大的宽度。在堆内存小于 32G 时可以通过编码、解码方式进行优化使得 JVM 可以支持更大内存配置。当堆内存空间大于 32G 时压缩指针参数可能会失效会强制使用 64 位即 8 字节来对 Java 对象寻址了。
#开启指针压缩
-XX:UseCompressedOops
#关闭指针压缩
-XX:-UseCompressedOops
但是这个 32GB 是和字节对齐大小相关的也就是 -XX:ObjectAlignmentInBytes 配置的大小默认是 8 字节Java 默认是 8 字节对齐。-XX:ObjectAlignmentInBytes 可以设置为 8 的整数倍最大 128如果设为 24那么配置最大的堆内存超过 96GB 压缩之指针会失效。 二、_mark 和 _klass 指针
JVM 中每个对象都有一个指向它自身类的指针不过这个指针只是指向具体的实现类而不是接口或者抽象类。只有是 64 位平台上启用了类指针压缩才会存在这个区域。对于 64 位平台为了压缩 JVM 对象中的 _klass 指针的大小引入类指针压缩空间Compressed Class Pointer Space _markmark word 一组标记描述了对象的状态包括对象默认哈希值如果没有覆盖默认的 hashCode 方法则哈希值在 hashCode 方法被调用之后会被记录到 MarkWord 之中、对象的形状是否是数组、锁状态偏向锁等锁信息偏向锁在 Java 15 中废弃Disable and Deprecate Biased Locking、数组长度如果标记显示这个对象是数组描述了数组的长度。MarkWord 的实现仅仅包含一个 uintptr_t 类型所以在 32 位和 64 位虚拟机上面大小分别是 4 字节和 8 字节。
_klass是指向对象实现的 Class 的指针。JDK7 之前指向的区域位于持久带Permanent GenerationJDK8 之后永久代带废弃引入了元数据区的概念Metaspace所以 JDK8 之后指向的是这个元数据区。这个指针可能是被压缩的即压缩指针Compressed OOPs。当开启对象压缩时占用 4 字节JVM默认开启关闭时占用 8 字节
class oopDesc {private:volatile markWord _mark; // 对象头 mark wordunion _metadata {Klass* _klass; // 类型指针执行类的指针narrowKlass _compressed_klass;} _metadata;
}
class markWord {private:uintptr_t _value;
}
32 位的 JVM _mark4 字节。mark word _klass4 字节。指向类的指针对象的内存布局中的第二个字段_klass在 32 位 JVM 中相对对象内存的位置的偏移量是 464 位的是 8指向的是内存中对象的类定义64 位的 JVM _mark8 字节_klass8 字节开启了指针压缩的 64 位的 JVM _mark8 字节_klass4 字节
三、类指针压缩空间
JDK1.8 移除了 permanent generationclass metadata 存储在 native memory meta space中其大小默认是不受限的可以通过 -XX:MaxMetaspaceSize 来限制。
在 JVM 使用 -XX:UseCompressedClassPointers 和 -XX:UseCompressedOops 开启 Compressed Class 的功能后会在 Metaspace 中开辟出一块新的空间Compressed Class Space这个空间不足会出现了 OOM可以通过设置 -XX:CompressedClassSpaceSize默认值为1G 的大小或者 -XX:-UseCompressedClassPointers 来关闭该功能。
如果开启了-XX:UseCompressedOops 及 -XX:UseCompressedClassesPointers默认开启则UseCompressedOops 会使用 32-bit 的 offset 来代表 java object 的引用而 UseCompressedClassPointers 则使用32-bit 的 offset 来代表 64-bit 进程中的 class pointer。可以使用 CompressedClassSpaceSize 来设置这块的空间大小CompressedClassSpace 分配在 MaxMetaspaceSize 里头即 MaxMetaspaceSize CompressedClassSpaceSize Metaspace area (excluding the Compressed Class Space) Size压缩指针后的内存布局 指针压缩概要
64 位平台上默认打开使用 -XX:UseCompressedOops 压缩对象指针 oops 指的是普通对象指针ordinary object pointerJava 堆中对象指针会被压缩成 32 位使用堆基地址如果堆内存低于 26G 时基地址为 0即指针的偏移量针对于堆的基地址使用 -XX:UseCompressedClassPointers 选项来压缩类指针 对象中指向类元数据的指针会被压缩成32位使用类指针压缩空间的基地址 四、元空间和类指针压缩空间的区别
类指针压缩空间只包含类的元数据比如 InstanceKlass, ArrayKlass 仅当打开了 UseCompressedClassPointers 选项才生效。为了提高性能Java 中的虚方法表也存放到这里。元空间包含类的其它比较大的元数据比如方法字节码常量池类常量池、运行时常量池等。