再战JVM (7) 对象的创建过程

26 篇文章 0 订阅

一. 对象的创建过程

  1. 根据new的对象,在常量池中定位所属类的符号引用
  2. 如果没有找到符号引用,说明这个类没有被加载,就对这个类进行加载
  3. 加载完成后,jvm为对象分配内存
  4. jvm将分配的内存空间初始化为0值
    当内存分配完成后,虚拟机将分配到的内存都初始化为零值(不包括对象头,引用类型初始值为null,基本类型为零值,布尔类型初始值为false),如果使用TALB这一过程也可以提前至TALB分配时进行,这个过程就可以解释 为什么对象创建后未赋值前就可以直接使用
  5. 设置这个对象的对象头信息
    虚拟机要为对象设置一些必要信息,例如这个对象是那个对象的实例、如何才能找到对象的元数据信息、对象的哈希码、GC的分代年龄等,这些都被设置在对象头(Object Header)中
  6. 执行构造方法,进行初始化
    找出当前对象所属类的继承关系,从继承链中最上层的父类开始,依次执行执行构造方法

虚拟机如何为对象分配内存?

  • 第一种虚拟机为对象分配内存叫做指针碰撞
    在这种方式中,认为堆中的内存都是绝对规整的,用过的内存都放在一侧,空闲的空间在另一侧,中间的指针作为指示器,为对象分配空间时,只是将指针向空闲的一侧移动出对象所需内存大小即可,这种方式叫做指针碰撞(Bump the Pointer)
  • 第二种虚拟机为对象分配内存叫做空闲列表
    如果堆中的内存不是规整的,空闲和被使用的内存交错存在,无法通过简单的指针碰撞方式分配内存,这个时候虚拟机需要维护一张表,用来记录哪些地方的内存可用,在可用内存中,取出对象所需大小,分配给对象,并更些列表

线程安全问题如何解决?

因为堆空间是线程共享的,多线程情况下,如果多个线程申请同一块内存空间,这样就程序异常了,jvm是如何解决的呢?

如果是在TLAB上分配对象的话,那么就不需要担心线程安全问题,如果不是在TLAB上分配内存的话,那么对分配内存的动作进行同步处理,即CAS(compare & swap)搭配失败重试的方式

二. 如何定位到对象

1. 通过直接指针访问对象

对象创建成功后,在栈或者方法区保存一个引用(reference),reference存储是对象地址,直接指向堆中对象的实例数据,同时一个存储一个指向对象类型数据的指针

在这里插入图片描述

2. 通过句柄访问对象

reference引用存储是句柄地址,句柄地址存储两个对象和类型数据两个指针,一个指向对象实例数据,一个指向对象类型数据
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值