10-对象的实例化内存布局与访问定位

简介: 10-对象的实例化内存布局与访问定位

1 对象的实例化


大厂面试题


美团:


对象在JVM中是怎么存储的?


对象头信息里面有哪些东西?


蚂蚁金服:


java对象头里有什么?


对象实例化


1.png


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


1.png


创建对象的步骤


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


1.png


为对象分配内存:


首先计算对象占用空间大小,接着在堆中划分一块内存给新对象。


如果实例成员变量是引用变量,仅分配引用变量空间即可,即4个字节大小


指针碰撞


如果内存是规整的,那么虚拟机将采用的是指针碰撞发(Bump The Pointer)来为对象分配内存。


意思是所有用过的内存在一边,空闲的内存在另一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅是把指针向空闲那边挪动一段与端详大小相等的距离罢了。如果垃圾收集器选择的是Serial、ParNew这种基于压缩算法的,虚拟机采用这种分配方式。一般使用带有Compact(整理)过程的收集器时,使用指针碰撞


如果内存不是规整的,已使用的内存和未使用的内存相互交错,那么虚拟机将采用的是空闲列表法来为对象分配内存。


意思是虚拟机维护了一个列表,记录上哪些内存块是可用的,再分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的内容。这种分配方式称为”空闲列表“(Free List)”。


初始化分配空间


将对象的所属类(即类的元数据信息)、对象的HashCode和对象的GC信息、锁信息等数据存储在对象的对象头中。这个过程的具体设置方式取决于JVM实现。


设置对象的对象头


将对象的所属类(即类的元数据信息)、对象的HasdCode和对象的GC信息、锁信息等数据存储在对象的对象头中。这个过程的具体设置方式取决于JVM实现。


执行init方法进行初始化


在Java程序的视角看来,初始化才正式开始。初始化成员变量,执行实例化代码块,调用类的构造方法,并把堆内方法的首地址赋值给引用变量。


因此一般来说(由字节码中是否跟随这invokespecial指令所决定),new指令之后会接着就是执行方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象就算完全创建出来。

/**
 * 测试对象实例化的过程
 * ① 加载类元信息 ② 为对象分配内存 ③ 处理并发问题 ④ 属性的默认初始化
 * ⑤ 设置股对象头的信息 ⑥ 属性的显示初始化、代码块中初始化、构造器初始化
 *
 * 给对象的属性赋值的操作
 * ① 属性的默认初始化 ② 显式初始化 / ③ 代码块中初始化 ④ 构造器中初始化
 */

1.png1.png1.png


2 对象的内存布局

1.png1.png



3 对象的访问定位


1.png


JVM是如何通过栈帧中的对象引用访问到其内部的对象实例的呢?


1.png


句柄访问(HotSpot并没有使用)


1.png


直接指针(HotSpot使用)


1.png

目录
相关文章
|
17天前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
39 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
6天前
|
缓存 算法 数据处理
如何选择合适的内存访问模式
【10月更文挑战第20天】如何选择合适的内存访问模式
17 1
|
8天前
|
存储 容器
内存越界访问(Out-of-Bounds Access)
【10月更文挑战第12天】
72 2
|
8天前
|
Rust 编译器
|
17天前
|
Java 测试技术 Android开发
让星星⭐月亮告诉你,强软弱虚引用类型对象在内存足够和内存不足的情况下,面对System.gc()时,被回收情况如何?
本文介绍了Java中四种引用类型(强引用、软引用、弱引用、虚引用)的特点及行为,并通过示例代码展示了在内存充足和不足情况下这些引用类型的不同表现。文中提供了详细的测试方法和步骤,帮助理解不同引用类型在垃圾回收机制中的作用。测试环境为Eclipse + JDK1.8,需配置JVM运行参数以限制内存使用。
26 2
|
17天前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
36 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
298 0
|
5天前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
13 1
|
10天前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
14天前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。