Java中如何去计算一个对象的内存占用?一个对象有哪些部分组成
- 对象的组成部分
- 1. 对象头
- 1.1 MarkWord 固定4或者8个字节
- 1.2 Klass Word 指向类的指针 4个字节
- 1.3 数组长度array length 固定4或者8个字节
- 2.2 实例数据
- 2.3 对齐填充
- 计算一个对象的内存占用
以HotSpot为例
对象的组成部分
对象的组成部分主要是三个部分:对象头、实例数据、对齐填充
其中对象头又分为三个部分:MarkWord、指向类的指针、数组长度(如果对象是数组的话,如果不是则没有此部分)
1. 对象头
1.1 MarkWord 固定4或者8个字节
在32位虚拟机中,占4个字节
在64位虚拟机中,占8个字节
Mark Work存储的是对象自身运行时的数据,比如:锁标志位;是否偏向锁;GC分代年龄;对象的hashCode;获取到该锁的线程的线程ID;偏向时间戳(Epoch)等等。
1.2 Klass Word 指向类的指针 4个字节
对应JVM位数,如果是64位的那么占用8个字节,如果32位占用4个字节,在开启压缩的情况下可以压缩成8->4个字节。
Java对象存放在堆中,但其类信息存放在方法区中,所以Klass word指向该对象的类信息。
1.3 数组长度array length 固定4或者8个字节
如果当前对象是数组,才有此数组长度字段。
如果jvm是32bit,则数组长度是32bit;如果jvm是64bit,则数组长度是64bit
2.2 实例数据
具体的对象属性内存占用大小。
对象的实例数据就是对象在java代码中的属性(包括父类属性以及自己的属性)和值。
2.3 对齐填充
因为jvm要求Java对象占用内存的大小是8byte的倍数,因此需要把对象的大小补齐至8byte倍数。
计算一个对象的内存占用
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
public class WordFilter {
private long aLong = 0L;
private long bLong = 0L;
private long cLong = 0L;
private byte aByte;
public static void main(String[] args) {
System.out.println(ClassLayout.parseInstance(new WordFilter()).toPrintable());
}
}
对象头部分等于 8+4 = 12个字节
实例数据大小 long (8x3) + byte (1x1)=25字节
由于 37不是8的倍数
对其填充为 40
如有错误欢迎指正