对象创建过程
当new一个对象的时候,首先会检查这个对象是否已经被类加载器加载,没有加载则按照当前的类加载器去加载(全盘委托机制)有加载或加载完毕后为其分配内存空间。
分配内存空间
在类加载检查通过后,接下来虚拟机将为新生对象分配内存。
划分内存的方法:
- 指针碰撞 :(默认使用指针碰撞)
如果java堆中的内存是规范的,那么一边是使用过的内存一边是空的内存,那么会在中间加一个指针作为分界点的指示器,分配的内存就是把指针向空闲的位置 挪一段与对象大小相同的位置即可 - 空闲列表
如果Java堆中的内存并不是规整的,就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例, 并更新列表上的记录
初始化
内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头)这一步叫初始化
设置对象头
然后就要设置对象头虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头Object Header之中。
执行<"init"> 方法
就是为属性赋值,赋上程序员赋的那个值,并不是初始化中的零赋值
对象的组成部分
对象是由三部分组成:对象头(Header)、 实例数据(Instance Data)和对齐填充(Padding)。
对象头
对象头内分为三部分
1.Mark Word
Mark Word在32位JVM中的长度是4个字节,在64位JVM中长度是8个字节
用于存储对象自身的运行时数据, 如哈 希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时 间戳等
32位的mark word图
2.Klass Pointer类型指针(开启压缩占4个字节,未开启占8个字节)
对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
3.数组长度
4个字节,只有数组对象有
示例数据
对象的实例数据就是在代码中能看到的属性和他们的值。
对齐填充
因为JVM要求java的对象占的内存大小应该是8个字节的倍数,所以后面有几个字节用于把对象的大小补齐至8个字节的倍数