【JVM】对象实例化

对象实例化

对象创建过程

  1. 判断对象是否被加载, 加载类元信息
    虚拟机遇到一条new指令, 首先去检查这个指令的参数能否在Metaspace的常量池中定位到一一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化。( 即判断类元信息是否存在).如果没有,那么在双亲委派模式下,使用当前类加载器以ClassLoader+包名+类名为Key进行查找对应的.class文件。如果没有找到文件,则抛出ClassNotF oundException异常,如果找到,则进行类加载,并生成对应的Class类对象
  2. 分配内存, 对象所需内存的大小在类加载完成后便可完全确定,如果实例成员变量是引用类型,则分配4字节
    • 如果内存规整:指针碰撞
      所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那 个指针向空闲空间方向挪动一段与对象大小相等的距离
    • 如果内存不规整: 空闲列表
      维护列表,记录哪些内存块是可用的,在分 配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录
  3. 处理并发问题
    采用 CAS 失败重试, 区域加锁保证更新原子性
    每个线程预留 TLAB
  4. 初始化分配到的空间
    属性默认初始化:零值
  5. 设置对象的对象头
    对象是哪个类的实例、如何才能找到 类的元数据信息、对象的哈希码(实际上对象的哈希码会延后到真正调用O bject ::hashCode()方法时才计算)、对象的GC分代年龄等信息
  6. init 方法初始化
    属性显式初始化:显示初始化, 代码块初始化, 构造器初始化

对象内存布局

  1. 对象头
    • 运行时元数据
      • hashCode
      • GC 分代年龄
      • 锁状态标志
      • 线程持有的锁
      • 偏向线程ID
      • 偏向时间戳
    • 类型指针
      指向元数据 InstanceClass ,确定对象所属的类型
  2. 实例数据
    对象真正存储的有效信息,包括定义的各种类型字段
  3. 对齐填充
public class Customer{
    int id = 1002;
    String name;
    Account acct;
    
    {
        name = "匿名";
    }
    public Customer(){
        acct = new Account();
    }
}
class Account{
}

image-20200516110826437

JVM 如何通过对象引用找到对象实体?
  1. 句柄访问:
    空间多,效率低;
    对象移动方便

    image-20200516111559663

  2. 直接指针
    image-20200516111750360

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值