网站开发成本网站开发90天
参考尚硅谷JVM 102 - 106 集
首发地址:地址
 
1、JVM对象的实例化
1.1 对象的创建方式
对象有一下几种创建对象的方式
- new
 
Object object = new Object();
 
- Class的newInstance()
 
Object object = Object.class.newInstance();
 
- Constructor的newInstance(XXX)反射获取构造器,构造器.newInstance()
 
Object Object = Object.class.getConstructor().newInstance();
 
- clone() 要想使用clone,必须实现Cloneable并重写clone方法
 
Test test = new Test();
Object clone = test.clone();
 
-  
反序列化(备注:需要实现序列化接口并且要先有序列化文件)
 -  
第三方库
Objenesis 
1.2 创建对象的步骤
创建对象有以下几种步骤:
- 1、判断对象对应的类是否加载、链接、初始化。
 - 2、为对象分配内存 
- 如果内存规整 > 指针碰撞
 - 如果内存不规整 
- 虚拟机需要维护一个列表
 - 空闲列表分配
 
 
 - 3、处理并发安全问题 
- 采用 
CAS配上失败重试保证更新到的原子性 - 每个线程预先分配一块 
TLAB 
 - 采用 
 - 4、初始化分配到的空间 
- 所有属性设置默认值,保证对象实例字段在不赋值的时可以直接使用
 
 - 5、设置对象的对象头
 - 6、执行 
init方法进行初始化 
2、对象的内存布局
对象的内存布局不是JVM规范的一部分,属于实现的细节,Hotspot将对象分成3部分: 对象头、实例数据、对齐填充 。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F3jLC5aT-1673618806604)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20230113212918686.png)]](https://img-blog.csdnimg.cn/3898dfbef3e947b681751a4a577f5dfe.png)
详细图:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q8uInd2y-1673618806605)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20230113203153023.png)]](https://img-blog.csdnimg.cn/d5734f942b9b44be81ef298c4aeeae17.png)
🌲 常见面试题
1、对象在JVM中是如何存储的呢?
2、对象头信息里面有哪些东西?
3、Java对象头中有什么?
答案参考:
地址
3、对象访问定位
首先我们要知道 JVM 是如何通过栈帧中的对象引用访问到其内部的对象实例的呢?
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dt6168GG-1673618806605)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20230113214628427.png)]](https://img-blog.csdnimg.cn/6d34115a45c144219d19f576133bd637.png)
我们的 Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。由于 reference 类型在 《Java虚拟机规范》 里面只规定了它是一个指向对象的引用,并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置,所以对象访问方式也是由虚拟机实 现而定的,主流的访问方式主要有使用 句柄和直接 指针两种。
3.1 句柄指针
·如果使用句柄访问的话,Java 堆中将可能会划分出一块内存来作为句柄池,reference 中存储的就 是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息,其结构如下图:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-COTm6Qum-1673618806605)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20230113214928852.png)]](https://img-blog.csdnimg.cn/aa8a43a60dbe440c83b1126c548cf9c8.png)
优点:
使用句柄来访问的最大好处就是 reference 中存储的是稳定句柄地 址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而 reference 本身不需要被修改。
3.2 直接指针
使用 直接指针 访问的话,Java 堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference 中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问 的开销,如下图:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cuQSbyXZ-1673618806606)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20230113215128591.png)]](https://img-blog.csdnimg.cn/66935ec72e74421fbb763959ed7c0849.png)
优点:
使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销,由于对象访 问在Java中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本。
⚠️ 注意:
HotSpot使用的是直接指针访问。
