欧尼酱讲JVM(18)——对象实例化内存布局与访问定位

目录

对象的实例化

创建对象的几种方式

从字节码角度看对象的创建过程

对象创建的六个步骤

第一步:判断对象对应的类是否加载、链接、初始化

第二步:为这个对象分配内存

第三步:处理并发安全问题

第四步:初始化内存分配到的空间

第五步:设置对象的对象头

第六步:执行init方法进行初始化

对象的内存布局

内存布局包括什么

图解内存布局

对象访问定位

句柄访问

使用句柄方式的好处 

直接指针(HotSpot采用此种方式)

使用直接指针的好处

直接内存

直接内存是什么

NIO解释

查看直接内存的占用与释放

直接内存的OOM与内存大小的设置


对象的实例化

创建对象的几种方式

  • new
    • 最常见的方式
    • 变形1:Xxx的静态方法
    • 变形2:XxxBuilder/XxxFactory的静态方法
  • Class的newInstance():反射方式,只能调用空参的构造器,权限必须是public
  • Constructro的newInstance(Xxx):反射的方式,可以调用空参、两参的构造器,权限没有要求
  • 使用clone():不调用任何构造器,当前类需要实现Cloneable接口,实现clone()
  • 使用反序列化:从文件中、从网站中获取一个兑现的二进制流
  • 第三方库Objenesis

从字节码角度看对象的创建过程

举个栗子:

public class ObjectTest {
    public static void main(String[] args) {
        Object obj = new Object();
    }
}

 从字节码角度看:

 new操作符在做什么呢?

答:

  1. 到字符串常量池找到#2,对应到方法区中看,是不是已经把Object类进行加载了?如果没有加载就需要使用类的加载器把java.lang包下的Object加载一下。
  2. 完了之后,先在方法区把Object类加载过来。new操作符还会在堆空间中开辟一个Object对象的空间(Double  Lang占8个字节,其他占4个字节)并进行临值初始化(double默认值0.0.boolean默认0.int默认0)。

以上就是new要做的事情。

dup:就是复制,在栈空间中的操作数栈,把当前生成的变量的引用复制一份,这样就有两个引用指向堆空间的实体,为什么有两个呢?栈底的作为赋值操作,上面的作为一个句柄去调用相关的方法。

invokespecial:构造器相关,把形参压入操作数栈,以及对堆空间的实例进行显示初始化等!

astore:把当前变量从操作数栈取出放到对应的局部变量表中。

对象创建的六个步骤

前面所述是从字节码角度看待对象的创建过程,接下来从执行步骤角度来分析。

一共有六个步骤:

  1. 判断对象对应的类是否加载、链接、初始化
  2. 为对象分配内存
    1. 如果内存规整——指针碰撞
    2. 如果内存不规整——虚拟机需要维护一个列表,空闲列表分配
  3. 处理并发安全问题
    1. 采用CAS配上失败重试保证更新的原子性
    2. 每个线程预先分配一块TLAB
  4. 初始化分配到的空间——所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用
  5. 设置对象的对象头
  6. 执行init方法进行初始化

第一步:判断对象对应的类是否加载、链接、初始化

虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化( 即判断类元信息是否存在)。如果没有,那么在双亲委派模式下,使用当前类加载器以ClassLoader+包名+类名为Key进行查找对应的.class文件。如果没有找到文件,则抛出ClassNotFoundException异常,如果找到,则进行类加载,并生成对应的Class类对象。

当加载完类之后,对象在堆空间占用多大的内存大小已经确定下来了。

第二步:为

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值