java一个引用多大,java一个对象多大?

最近在看点不知道什么鬼的东西,看得到了一个让我眼前一亮的新东西,感觉很有趣,记录一下;

我们怎么知道一个java对象的大小呢?比如HashMap map = new HashMap<>();,这个map对象在堆中多大呢?占多少个字节呢?

我们可以借助apache的一个类RamUsageEstimator来计算,例如下面这种:

org.apache.lucene

lucene-core

6.6.1

Integer integer= new Integer(10);

HashMap map = new HashMap<>();

System.out.println(RamUsageEstimator.shallowSizeOf(integer));//16

System.out.println(RamUsageEstimator.shallowSizeOf(map)); //48

我们可以看到最后计算出来的一个Integer是16个字节,一个HashMap是48个字节;

这个时候肯定会有人说,(#`㉨´)凸不对呀,不是说int类型是4个字节的吗?为什么包装类型Integer的就是16个字节了呢?

要知道这个问题,首先我们要知道在java堆中实例化的对象是由什么构成的?前面博客说了的,这里简单的提一下,分三部分:对象头,实例数据,对齐填充

8cb1091fd39c785db889161d5afa515d.png

主要说一下对象头,对象头由两部分组成,64位jvm中markword占8个字节(一般都是64位的吧,32位的虚拟机就占4个字节),第二部分是klass类型的指针占4个字节!如果是数组,那么此处还有第三部分,数组长度占4个字节;

然后上面例子中Integer的对象头应该是8+4=12,然后实例数据我们需要看Integer类以及父类中有几个实例变量,只有一个,下图所示(注意,是实例变量,不能是native和static修饰的),如果是引用类型就占4个字节用于记录地址;int类型4个字节,于是12+4=16,刚好是8的倍数,无需对齐填充;

114ec8fca25a03f44ba1b1533403d83f.png

我们再说说那么HashMap,对象头也是12,实例数据,我们要看看HashMap的父类有两个属性,是引用类型,每一个占4个字节;

299f5907ddc0f55a8a7a1577d1ad8f00.png

再看看HashMap本类中有几个属性,可以看到6个,共占24个字节

transient Node[] table;//引用类型,占四个字节

transient Set> entrySet;//引用类型,占四个字节

transient int size;//int类型,4个字节

transient int modCount;//int类型,4个字节

int threshold;//int类型,4个字节

final float loadFactor;//int类型,4个字节

所以就是12+4+4+24=44,由于java对象占的字节数必须要是8的倍数,所以对齐填充,在最后补4个字节,所以总共就是48个字节,很容易吧!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值