1--------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
32位系统 |
64位系统 |
64位开启指针压缩的情况下 |
若为数组对象 |
|
MarkWord标记位 |
4字节 |
8字节 |
8字节 |
|
|
Class Pointer |
4字节 |
8字节 |
4字节 |
|
|
Length |
|
|
|
4字节 |
32位系统 对象头占用空间= 4 + 4 = 8 byte
64位系统 对象头占用空间= 8 + 8 =16 byte
64位开启指针压缩 对象头占用空间= 4 + 8 = 12 byte
注:
若为数组对象,对象头占用空间 + 4 byte
静态属性不算在对象大小内
2--------------------------------------------------------------------------------------------------------------------------------------------------------------------
从上文的分析中可以看到,64位JVM消耗的内存会比32位的要多大约1.5倍,这是因为对象指针在64位JVM下有更宽的寻 址。
对于那些将要从32位平台移植到64位的应用来说,平白无辜多了1/2的内存占用,这是开发者不愿意看到的
从JDK 1.6 update14开始,64位的JVM正式支持了 -XX:+UseCompressedOops 这个可以压缩指针,起到节约内存占用的新 参数。JDK 1.8,默认该参数就是开启的。
OOP的全称为:Ordinary Object Pointer,就是普通对象指针。启用CompressOops后,会压缩的对象:
每个Class的属性指针(静态成员变量);
每个对象的属性指针;
普通对象数组的每个元素指针。
当然,压缩也不是所有的指针都会压缩,对一些特殊类型的指针,JVM是不会优化的,例如指向PermGen(1.8废弃)的Class对象指针、本地变量、堆栈元素、入参、返回值和NULL指针不会被压缩。
算了,直接看他吧,他这篇文章灰常棒:http://www.ideabuffer.cn/2017/05/06/Java%E5%AF%B9%E8%B1%A1%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80/