1. 首页
  2. Java

java一个对象多大?

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

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

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

复制代码
<dependency>
   <groupId>org.apache.lucene</groupId>
   <artifactId>lucene-core</artifactId>
   <version>6.6.1</version>
 </dependency>

Integer integer = new Integer(10); HashMap<String,Object> 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堆中实例化的对象是由什么构成的?前面博客说了的,这里简单的提一下,分三部分:对象头,实例数据,对齐填充

java一个对象多大?

 

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

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

java一个对象多大?

 

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

java一个对象多大?

 

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

复制代码
 
transient Node<K,V>[] table;//引用类型,占四个字节

transient Set<Map.Entry<K,V>> 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个字节,很容易吧!

本文来自投稿,不代表程序员编程网立场,如若转载,请注明出处:http://www.cxybcw.com/188390.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code