java对象占用内存

 

大家可能遇到过Object o = new Object(),在内存中占用多少空间。

这里可以使用JOL工具类打印对象头。具体使用方法问度娘

这里首先要了解java内存对象的布局:markword、指针类型 、实例数据(Instance Data)和对齐填充(Padding)。无论是32位还是64位的HotSpot,使用的都是8字节对齐。也就是说每个java对象,占用的字节数都是8的整数倍。

注意:对象头(Header) = markword+指针类型

markword
类型指针(class pointer)
实例数据(instance data)
对齐(padding)

我们在cmd窗口中输入命令java -XX:+PrintCommandLineFlags -version,如下图

可以看出Jvm是64位,指针长度也就是8Bytes.

 UseCompressedClassPointers:压缩指针,默认把指针压缩成4个字节

UseCompressedOops:普通对象指针。例如String a = new String() , 栈中变量a指向堆中new String()的对象指针,这里也是被默认压缩成4B

所以我们默认开启压缩的情况下,new 出来的对象头占用是markword(8)+class pointer(4) = 12个字节。相反,未开启压缩则是8+8 =16个字节。

1.基本数据类型占用的字节数,JVM规范中有明确的规定,无论是在32位还是64位的虚拟机,占用的内存大小是相同的。

原生类型内存占用空间(bytes)
boolean                      1
byte                            1
short                           2
char                            2
int                               4
float                            4
long                            8
double    8
对象头32位(jvm)

64位(jvm)

关闭-XX:-UseCompressedOops指针压缩

64位(jvm)

开启XX:+UseCompressedOops)指针压缩

reference类型4Bytes8B4B
new Object类型8B16B12B
Array类型 24B16B




2.对象内存布局中的实例数据,不包括类的static字段的大小,因为static字段是属于类的,被该类的所有对象共享。

现在在来回答开始的问题:如果是64位jvm上开启指针压缩,new Object对象头占用了 16B,不需要padding。

Double[] d = new Double[3] 对象占用多少空间?

我们先来计算64位系统未开启指针压缩的new Double[0]占用空间

1.首先它是数组对象,对象头占用空间是24B

2.数组长度是3, 包装类型Double占用的空间是8B

结果24+3*8 = 48,是8的倍数,不需要Padding,所以最后得出 64位系统未开启指针压缩占用空间是 48B。

根据上面的知识,我们来计算下面这个对象占用的内存空间

public class User{

   int a ;
   String b ;
}

 开启默认压缩的情况

 1. new的对象头占用空间 = markword(8)+ class pointer(4) = 12B

 2. 基本类型 a 占用空间 = 4B

 3.String类型普通指针(开启了压缩) = 4B

 4.在padding 4个字节 可以被8整除

 所以最终占用24个字节

这里也有篇不错的文章,大家可以看看

https://www.cnblogs.com/zhanjindong/p/3757767.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值