JVM:Java对象的创建与内存布局

前言

在开发过程中如果要创建一个对象可以通过以下几种方式:
new、克隆(Clone)、反射(Class.forName(“类全限定名”).newInstance(),Constructor类的newInstance)。
今天只针对通过关键字new来创建对象作分析,通过new创建一个对象的方式如下:

1
Object o = new Object();

但在new之后J虚拟机还会经过一系列的操作才能创建,今天来记录一下new之后的事情,以及对象的组成结构。

对象的创建

示意图


创建步骤

  • 类的检查
    new指令之后首先在常量池中检查是否能定位到该类符号的引用。
    如果没有定位到,则进行类的加载、解析和初始化
  • 为对象分配内存
    虚拟机将为对象分配内存,即把一块确定大小的内存从 Java 堆中划分出来
    这种分配方式会根据堆内存是否整齐分成两种形式。
    1.堆内存整齐:指针碰撞
    2.堆内存零散:闲散列表
    另外,为对象分配内存会引发线程不安全问题,解决方式是:
    把内存分配行为 按照线程 划分在不同的内存空间进行
  • 内存空间初始化为零值
    内存分配完成后,虚拟机需要将分配到的内存空间初始化为零(不包括对象头)
  • 设置对象
    主要是设置对象头,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息

对象内存布局

对象头

如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等

实例数据

对象真正有效的信息,即:代码中定义的字段内容

对齐填充

存储的信息:占位符,占位作用,因为对象的大小必须是8字节的整数倍。对象头的大小也是8字节的整数倍,如果实例数据不是8的整数倍的话(没对齐),则需要存储占位符,对齐填充。