创建一个object对象,Object o = new Object();
,首先我们要明确知道创建对象的那一行代码的存储位置,
Object相当于一个Object类的模板,类加载的时候放在方法区,存放类的信息
o:在方法体中,随着方法的调用,存储在栈中栈帧信息中,
tips:栈帧包括局部变量表,操作数栈,动态链接,返回地址
new Object():创建的对象信息放在堆空间中
了解到了对象的存储位置,这时我们要知道对象在堆中存放哪些信息?
对象在堆内存中存储布局可以划分为三个:对象头,实例数据,填充属性
对象头:包括Markword和类型指针
一个对象中都应该包含一下:
这些基本信息在对象头中markword都记录着,比如GC标记信息,GC次数,同步锁标记,偏向锁持有者,hashcode值
2.实例数据:可以认为是对象中的一些数据,比如String id;
3.填充属性:当创建的对象占用内存大小不为8个字节的倍数,会对对象的内存占用补充为8的倍数
在64位操作系统当中,对象头中Mark word为8字节,类型指针为8字节,在没有实例数据的情况下,占用内存大小为16个字节
Markword分布图:对象布局,GC回收和后面锁升级就是对象标记MarkWord里面标志位的变换
25+31+1+4+1+2 = 64位
偏向锁状态时:当线程第一次访问同步代码块并获取锁时,虚拟机将会把对象头中的标志位设为01,同时使用CAS操作把获取到这个锁的线程id记录在对象的Markword中
轻量级状态:将对象头中的数据都置换为指向栈中锁的记录的指针
重量级状态:将对象头中的数据都置换为指向重量级锁的指针