Java对象的创建和访问

版权声明: https://blog.csdn.net/ZHENZHEN9310/article/details/86476331

一、对象创建流程

Java对象都是通过关键字new指令,来创建的。

在这里插入图片描述

1、类加载检查

检查能否能在常量池中定位到一个类的符号引用
检查该类符号引用代表的类是否已被加载、解析和初始化过

2、为对象分配内存并初始化

对象所需内存的大小在类加载完成后便可完全确定
内存分配 根据 Java堆内存是否绝对规整 分为两种方式:指针碰撞 & 空闲列表
内存分配完成后,虚拟机对内存空间进行初始化(不包括对象头)

给对象分配内存会存在线程不安全的问题。
1、虚拟机采用 CAS + 失败重试的方式 保证更新操作的原子性

2、每个线程在 Java堆中预先分配一小块内存(本地线程分配缓冲(Thread Local Allocation Buffer ,TLAB))
哪个线程要分配内存,就在哪个线程的TLAB上分配,只有TLAB用完并分配新的TLAB时才需要同步锁。

3、虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定。

二、对象的访问定位

Java中是通过引用(reference)来实现对象实例(堆中)的访问的。

由于reference 类型在Java 虚拟机规范里面只规定了一个指向对象的引用,并没有定义这个引用应该通过哪种方式去定位,以及访问到Java 堆中的对象的具体位置,因此不同虚拟机实现的对象访问方式会有所不同,主流的访问方式有两种:使用句柄和直接指针。

1、使用句柄

reference中存储的就是对象的句柄地址,Java 堆中将会划分出一块内存来作为句柄池,而句柄中包含了对象实例数据和类型数据。

栈中reference存储的是稳定的句柄地址,在对象移动时,只会改变句柄中的实例数据指针,而栈中reference数据不需修改,适用于需频繁移动对象
在这里插入图片描述

1、直接指针

reference 中直接存储的就是对象地址,Java 堆对象的布局中就必须考虑如何放置访问类型数据的相关信息。

速度快,不需要二次定位,适用于需频繁访问对象。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ZHENZHEN9310/article/details/86476331