怎么计算一个对象占用的内存

怎么计算一个对象占用的内存

这应该是很多人在面试过程中遇到过的一个面试题~ 好多人在听到这么一个问题的时候都会瞬间懵逼,也有的人我记住了基本数据类型的占用内存和对象引用是4个字节大小。 这是正确的思考方向,但是不够全面。 下面就一步一步解析对象的组成有哪些。

对象分为三块存储区域

  1. 对象头(obect header)

对象头又包含两部分,总共占用大小12字节,如下: 对象标记(markOop)。存储对象在运行时的数据,如:哈希码、GC标记、锁信息、线程关联信息。在64位的jvm上占用 8个字节。需要补充一点的是,对象标记部分的存储格式是非固定的,具体要看jvm的实现。这样设计的目的是为了能存储 更多数据。

类元信息(klassOop)。存储对象指向的类元信息的首地址,也就是Klass的首地址。Klass存放在哪?在方法区。不知道 的可以去看看内存模型的介绍。类元信息占4个字节。

  1. 实例数据(Instance Data)

存储本类对象的实例成员变量和父类所有可见的成员变量

例子a:

public class BaseEntity {

    private int mId;

}
复制代码

BaseEntity类只有一个私有的成员变量,所以它new出来的对象占用(4+12)字节。

例子b:

public class BaseEntity {

    private int mId;

    public long mLong;

    protected double mDouble;
}
复制代码
public class SampleEntity extends BaseEntity {

}
复制代码

在BaseEntity内新增一个public的long成员变量和protected的double成员变量。所以它的实例对象占用(4+8+8+12)字节。

继承该BaseEntity得到子类SampleEntity。SampleEntity继承了父类的mLong和mDouble。所以实例对象占用(8+8+12)字 节。所有基本类型的占用大小本文后面会介绍。

  1. 对齐填充(Padding)

对象的存储空间的分配单位是8字节,当对象大小不是8的整数倍的时候需要填充对其。如上例子2,占用内存是28,不是8的整 数倍,这个时候需要填充4个字节,即32。所以实际分配的是32个字节。

9种基本数据类型

聊到这里,大概的思考流程是明了了,但是还需要补充基本数据类型占用内存的大小,以及在计算过程中实例对象该怎么处理。

什么,不是8种吗?对,8+1种。hhh~

前8种

类型 默认值 占用内存(字节)
boolean false 1
byte (byte)0 1
char '\u0000' 2
short (short)0 2
int 0 4
long 0L 8
float 0.0f 4
double 0.0d 8

第9种

类型 默认值 占用内存(字节)
对象引用变量(Refrence Varible) null 4

假设对象引用变量简称refV,实际对象(Referred Object)为:refO;

refV存储引用指向的实际对象的存储地址的首地址。可以直接用==做等值判断。作为对象的引用变量,refV无论指向包装类,集合类,字符串类,自定义类,还是数组,均占用4字节。

refO最小占用12字节,即只有对象头,但是要对齐填充,所以最小分配的内存空间是16字节。

例子c:

public class RefDemo {

    private short mShort;

    private BaseEntity mBaseEntity;

    private SampleEntity mSampleEntity = new SampleEntity();

}

复制代码

mShort占2字节;mBaseEntity未指向任何实例值为null且占用4字节;mSampleEntity指向了一个refO实例对象,注意 mSampleEntity只是个refV引用类型数据结构,表示的是refO实例对象的首地址,占用4个字节。补充一下,new 出来的 SampleEntity实例存放在堆里,new出来的RefDemo实例也是存放在堆里,RefDemo实例内的mSampleEntity引用变量指向 SampleEntity实例存储。

所以一个RefDemo实例占用(2+4+4+12)字节,填充对齐后是24字节,即实际分配了24个字节的存储空间。

结语:

计算一个对象的占用内存大小要注意:父类继承下来的基本数据类型和引用变量,一定要理解引用变量和引用变量指向的实例对象的区别。

转载于:https://juejin.im/post/5cafe99a6fb9a068553e14d2

你可能感兴趣的:(怎么计算一个对象占用的内存)