45.创建对象的方式以及创建对象的步骤

1.创建对象的方式

创建对象的方式有6种。
1.通过new关键字。new关键字是通过调用构造方法实现的。
2.通过ClassnewInstance方法。这是反射的方式,只能调用无参构造器,权限必须是public
3.通过ConstructornewInstance方法。这也是反射的方式,可以调用无参、带参构造器,权限没有要求
4.通过clone()。不调用任何构造器,当前类需要实现Cloneable()的接口,实现clone()方法
5.使用反序列化方式。从文件中、网络中获取一个对象的二进制流
6.第三方Objeneis
在这里插入图片描述

2.创建对象的步骤

在这里插入图片描述

  • 1.判断对象对应的类是否加载、链接、初始化。
    虚拟机遇到一条new指令时,首先检查这个指令的参数能否在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载、链接和初始化过。如果没有,则先进行相应的类的加载过程。
  • 2.为对象分配内存
    首先计算对象所需的内存的大小,对象所需内存的大小在类加载完成后便可完全确定。
    a)如果堆空间的内存你是规整的:使用指针碰撞的方式分配内存。
    jvm将堆区抽象为两块区域,一块是已经被其他对象占用的区域,另一块是空白区域,中间通过一个指针进行标注,这时只需要将指针向空白区域移动相应大小空间,就完成了内存的分配,当然这种划分的方式要求虚拟机的对内存是地址连续的,且虚拟机带有内存压缩机制,可以在内存分配完成时压缩内存,形成连续地址空间,这种分配内存方式成为“指针碰撞”,但是很明显,这种方式也存在一个比较严重的问题,那就是多线程创建对象时,会导致指针划分不一致的问题,例如A线程刚刚将指针移动到新位置,但是B线程之前读取到的是指针之前的位置,这样划分内存时就出现不一致的问题,解决这种问题,虚拟机采用了CAS配上失败重试的方式来保证更新操作的原子性;
    在这里插入图片描述
    b)如果内存不规整(已使用的内存和未使用的内存相互交错):采用空闲列表的方式分配内存。
    虚拟机维护了一个列表,记录上哪些内存块是可用的,再分配的时候从列表中找到一块足够大的看见划分给对象实例,并更新列表上的内容。

具体使用哪种分配方式取决于垃圾收集器是否有压缩整理的功能。

  • 3.处理并发安全问题
    堆区是共享的,多线程同时创建对象的时候会具有并发安全的问题。处理并发安全问题的方式有两种。
    a)采用CAS(Compare and Start)失败重试以及区域加锁的方法来保证更新的原子性
    b)为每个线程分配的空间称为“本地线程分配缓冲(TLAB)”,是否启用TLAB需要通过 -XX:+/-UseTLAB参数来设定。JDK8默认打开。

  • 4.默认初始化分配到的空间。也就是对对象的字段赋0值,或者null值。

  • 5.设置对象的对象头。
    虚拟机对对象进行必要设置(如对象的哈希码,对象的GC分代年龄,该对象是哪个类的实例,如何才能找到类的元数据信息等),这些信息存放在对象的对象头中。

  • 6.执行init方法进行初始化。
    执行显示初始化、代码块中的初始化、构造器中的初始化。

更多JVM文章请访问我的JVM专栏:
https://blog.csdn.net/u011069294/category_10113093.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值