JVM之【Java对象在内存中的结构】
目录
前言
对象的组成部分
对象头
实例数据
对齐填充
查看对象的组成结构和大小
添加依赖
查看Object对象占用的内存大小
查看数组对象占用的内存大小
查看上面example1占用内存大小
查看上面example2占用内存大小
相关的JVM参数
前言
Java程序运行过程中,大多数的对象会被分配到堆空间中存储,本文主要介绍Java对象在内存中的组成结构
对象的组成部分
Java对象一般由三个部分组成:对象头、实例数据和对齐填充
对象头
由如下几个部分组成
- MarkWord,在64位虚拟机中占用8个字节
- 类型指针,在64位虚拟机中且开启了指针压缩时占用4个字节
- 数组长度(如果是数组对象),在64位虚拟机中占用4个字节
实例数据
下图中Example1类中有3个属性,两个int型一个long类型,此时对象example1的实例数据大小为:4+4+8=16字节
public class Example1 {// 4byteprivate int i1;// 4byteprivate int i2;// 8byteprivate long l1;public static void main(String[] args) {Example1 example1 = new Example1();}
}
下图中Example2类中有4个属性,2个int类型,1个long类型,1个引用类型(引用类型是直接存储指针的),在开启指针压缩时,example2的实例数据大小为:4+4+8+4=20字节
public class Example2 {// 4byteprivate int a;// 4byteprivate int b;// 8byteprivate long c;// 开启指针压缩占时占用4byteprivate Example1 e;public static void main(String[] args) {Example2 example2 = new Example2();}
}
对齐填充
在Java对象中,对齐填充可能存在也可能不存在,64位虚拟机规定Java对象的总大小必须是8的整数倍,所以当一个对象的头像头+实例数据大小不为8的整数倍时,会通过对齐填充的方式将对象的大小补齐成8的整数倍
查看对象的组成结构和大小
添加依赖
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.9</version>
</dependency>
查看Object对象占用的内存大小
代码示例
import org.openjdk.jol.info.ClassLayout;public class WatchObj {public static void main(String[] args) {Object object = new Object();System.out.println(ClassLayout.parseInstance(object).toPrintable());}
}
运行结果:大小为16字节(8字节的MarkWord + 4字节的类型指针 + 4字节的对齐填充)
查看数组对象占用的内存大小
代码示例
import org.openjdk.jol.info.ClassLayout;public class WatchObj {public static void main(String[] args) {Object object = new int[9];System.out.println(ClassLayout.parseInstance(object).toPrintable());}
}
运行结果:56字节(8字节MarkWord + 4字节类型指针 + 4字节数组长度 + 4*9字节数组空间 + 4字节对齐填充)
查看上面example1占用内存大小
代码实例
import org.openjdk.jol.info.ClassLayout;public class WatchObj {public static void main(String[] args) {Example1 object = new Example1();System.out.println(ClassLayout.parseInstance(object).toPrintable());}
}
运行结果:32字节(有4字节的对齐填充)
查看上面example2占用内存大小
代码示例
import org.openjdk.jol.info.ClassLayout;public class WatchObj {public static void main(String[] args) {Object object = new Example2();System.out.println(ClassLayout.parseInstance(object).toPrintable());}
}
运行结果:32字节(没有对齐填充)
相关的JVM参数
- [-XX:+UseCompressedOops]:开启指针压缩