Java对象模型:Java对象究竟占多少内存

Java对象模型

Java对象由 对象头+实例数据+padding填充三部分组成;

对象头

  • MarkWord:用于存储对象运行时的数据,好比 HashCode、锁状态标志、GC分代年龄等。这部分在 64 位操作系统下占 8 字节,32 位操作系统下占 4 字节;
  • 元数据指针:开启指针压缩时占4byte,未开启时占8byte,对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪一个类的实例。
  • 数组长度:只有是数组对象才有,若是是非数组对象就没这部分。这部分占 4 字节

数据实例就是存储对象内所有字段的数据,包括从父类继承的字段;

padding是对象的对齐填充部分,Java对象的大小必须是8字节的倍数,若对象的大小到最后不够8个字节就要补齐。

所以总结下来64位平台下对象大小的总体公式就是:

        对象头+实例数据+padding填充=(8byte+8byte=16byte)+ 数据实例 + padding填充;

        若开启指针压缩则对象头指针占内存缩小到4个字节,则对象头大小为12个字节;

        若对象是类型是数组,则对象头要再加上4个字节,未开启压缩时为20个字节,开启后为16个字节;

开启对象指针压缩

vm默认开启普通对象指针压缩(命令添加参数 -XX:+UseCompressedOops),但当最大堆大小超过32 GB时,JVM将自动关闭 oops 压缩。

注意:普通对象指针压缩(UseCompressedOops)默认就是开启的;

当 Java 堆大小大于 32GB 时也可以使用压缩指针。虽然默认对象对齐是 8 个字节,但可以使用 -XX:ObjectAlignmentInBytes 配置字节值。指定的值应为 2 的幂,并且必须在 8 和 256 的范围内。

除了对象指针压缩,还有类指针压缩:

-XX:+UseCompressedClassPointers:表示是否启用类指针压缩,因为对于任何一个jvm中的对象而言,其内部都有一个指向自己对应类(属于哪个class)的指针(Java习惯叫引用),在64位的Java虚拟机中,默认是启动压缩的;

基本类型对象占用内存空间

类型

占用空间(byte)

boolean

1

byte

1

short

2

char

2

int

4

float

4

long

8

double

8

引用类型占用内存空间:引用类型在 32 位系统上每个引用对象占用 4 byte,在 64 位系统上每个引用对象占用 8 byte。所以每声明一个引用,其本身也要占内存空间。

总结:

一个对象占用内存的大小算法,首先记住计算公式:对象头+实例数据+填充,一个非数组类型的空对象,即里面没有声明任何属性的对象,其理论大小只有对象头,在默认情况下是8+4=12个字节,但因为补齐填充所以最终是16个字节。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值