对象的构成主要是由对象头(header),实例数据(instance data),对齐填充(保证8字节的倍数) 组成的
他们的分布关系主要如下图所示 , 下面我会对他们的组成部门进行一一的讲解;
对象头主要包括对象标记 (markWord),类元信息(类型指针) , 当我们声明一个类时(没有变量),此时他就是一个对象头
//只有一个对象头
class MyClass{
}
问题1:对象标记主要保存什么?
它主要保存了对象的hashCode,锁指针,对象的分代年龄记录
问题2:他占用多大的字节?
在64位系统中,MarkWord占用了8个字节
问题1:类元信息主要保存什么?
类元信息存储的是指向对象类元数据的首地址,下面的2点
问题2:类元信息占用多大的字节?
在64位系统中,MarkWord占用了8个字节
问题2:类元信息有什么用?
对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
下面的代码就是有了实例数据的类
//有属性了; 有对象头,还有实例数据
class MyClass{
private String id;
}
它存放的是存放类的属性数据信息,包括父类的属性信息;
虚拟机要求对象起始地址必须是8字节的整数倍,填充数据不是必须存在的,仅仅是为了字节对齐这部分内存按8字节补充对齐。
在下面的代码案例: 对象头16字节+int 4 字节 + boolean 1字节 = 21字节; 因为对齐填充,(保证8字节的倍数
)最后得到是24字节;
//有对象头,还有实例数据
class MyClass{
//int 32位 4字节
private int id;
//boolean 1字节
private Boolean flag;
}
本次证明使用JOL(java object layout)证明 (分析对象在JVM的大小和分布) 观察对象的再JVM内存情况;
POM依赖
<dependency>
<groupId>org.openjdk.jolgroupId>
<artifactId>jol-coreartifactId>
<version>0.9version>
dependency>
demo示例
public class ReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//vm的细节详细情况
System.out.println(VM.current().details());
//所有对象分配的字节都是8的整数倍
System.out.println(VM.current().objectAlignment());
}
}
证明:
在这里有个疑问:为什么类型指针是4字节的?主要是他下面的开启了压缩指针;继续观看下节;
开启压缩指针了,会对填充字节造成一定影响;
步骤一:开启参数,开启了那些参数, 全部列出来
java -XX:+PrintCommandLineFlags -version
步骤二:
最后我们可以知道本次标题的问题答案,