Javashort占几个字节 java中shot占几个字节
转载
背景看h2源码的过程中,由于每个Page需要持久化,便使用一个字段存放写入文件时占用的字节大小,而我对java对象占用字节大小不甚清晰,便查找资料记录如下:
java对象在堆中如何存放java对象在堆中分为三个部分,分别是 对象头(Header),实例数据(Instance Data)和对齐填充(Padding) 对象头分为三个字段: - 8个字节
- 4个字节(32位JVM或64位JVM开启指针压缩)
- 8个字节(64位JVM且关闭指针压缩)
- 指向instanceklass
- 4个字节
- 只有数组对象会有此值,表示数组的长度
存储了Java对象hash、GC年龄、锁标记、class指针、数组长度等信息
实例数据当前对象中的实例字段。由基本数据类型和引用类型组成的。
对象填充VM要求对象大小须是8的整体数,该部分是为了让整体对象在内存中的地址空间大小达到8的整数倍而额外占用的字节数。
压缩指针- 32位HotSpot VM是不支持UseCompressedOops参数的,只有64位HotSpot VM才支持。
- 可通过
-XX:+UseCompressedOops 和-XX:-UseCompressedOops 进行开启和关闭 - java7和java8默认开启
为什么用压缩指针?- 4字节只能寻址到4G内存,不足;8字节可以寻址到232*4G内存,太多了
- 使用8bit表示oop( ordinary object pointer,一般对象指针),相较于4bit而言,会使所有应用程序运行时占用的空间大1.5倍
- 增加了GC开销
- 降低CPU缓存命中率
压缩指针原理- 确保所有的对象都是8bit对齐
- oop指向的地址只需要保存对象的起始位置即可,没必要寻址到8bit的每一位,那么oop指向的地址的后三位全是000,可以省略,也即oop可以表示
前32位+000 ,一共35位的地址,即23*4G=32G的内存
信息是否被压缩?哪些信息会被压缩?- 对象的全局静态变量(即类属性)
- 对象头信息:64位平台下,原生对象头大小为16字节,压缩后为12字节
- 对象的引用类型:64位平台下,引用类型本身大小为8字节,压缩后为4字节
- 对象数组类型:64位平台下,数组类型本身大小为24字节,压缩后16字节
哪些信息不会被压缩?- 指向非Heap的对象指针
- 局部变量、传参、返回值、NULL指针
展望- 所有对象16bit对齐,压缩指针可以表示64G内存(也可以此类推)
- 5字节oop,可以表示1024G内存;6字节oop,可以表示65536*4G内存
- 变长oop
|
对象头大小 | 开启指针压缩 | 关闭指针压缩 |
是数组对象 | 16byte | 20byte |
不是数组对象 | 12byte | 16byte |
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。