基础回顾——Java对象创建、内存分配、访问定位概述
来源:互联网 发布:数据透视图去掉汇总行 编辑:程序博客网 时间:2024/06/08 12:37
对象创建与内存分配
Java中创建对象并为其分配内存的过程如下:
Java语言层面执行new关键字
在Java中,通常使用new关键字来创建一个对象(还没有对象的可以试试^_^),对应在虚拟机中会触发一条new指令。
虚拟机处理new指令
当虚拟机触发一条new指令时,首先根据指令参数去常量池中检查是否有相关类的符号引用,进一步检查它是否已经被加载、解析和初始化,如果没有,则需要先加载类。对类加载相关的信息判断完成之后,才开始为对象分配内存。
为对象分配内存
根据堆内存的规整状态(堆内存是否规整又由垃圾收集器的算法规则决定)常用如下两种方式:
指针碰撞
适用于堆内存绝对规整,没有碎片,用过的内存在一边,未用过的内存在另一边的情况。两段内存之间放置一个边界指针,分配内存时仅需要把指针向空闲内存段移动对象大小的距离即可。
空闲列表
适用于堆内存无规则,用过的内存与空闲内存交错的情况。此时虚拟机维护一个记录内存使用状态的列表,分配内存时,寻找一块能容下对象大小的空闲片段,并更新列表记录。
说明:由于堆内存是线程共享区域,如果多线程同时为对象分配内存,则上述方法必然存在线程安全问题。通常可想到的方案是对内存分配动作进行同步加锁处理,但这种方式必然影响效率;另一种方案为采用TLAB(Thread Local Allocation Buffer)方式,即先为每个线程分配一块内存,然后哪个线程需要为对象分配内存时,就在各个线程的内存区域内部分配,这也可以保证各个线程间互不影响。当TLAB空间用完重新分配时,才需要同步处理。
将分配的内存空间初始化为零值
内存分配完成后,虚拟机有个初始化零值的过程,如果使用TLAB方式,此操作也可能提前到TLAB分配时进行。正因为如此,我们平时创建一个对象后,其字段有初始值,如int返回0,boolean返回false。
虚拟机对对象进行必要设置
主要是存储一些信息,如此对象属于哪个类、怎么样获取类的元数据、对象的hashcode、对象的GC分代年龄等信息,这些信息存放在对象的对象头中(对象在内存中的存储布局分为3个区域:对象头、实例数据、对齐填充)。
<init>
方法执行,完成对象的真正初始化上述5步之后,已经创建了一个对象了,但各个字段被置为零值,接下来会执行
<init>
方法,根据开发者的代码逻辑来初始化对象,这样才算真正完成了对象的创建。
对象访问方式
创建好Java对象之后,就需要使用对象。在虚拟机栈上只定义了一个指向堆内的引用,主流有两种方式去操作对象:
使用句柄
此种方案会在堆中创建一个句柄池,栈中的引用存储的是对象句柄的地址,因此栈中的引用指向堆中的句柄池中的某个句柄,而对象句柄则存储了对象实例数据和类型数据的信息(它们的具体地址),示意图(来自《深入理解Java虚拟机》)如下:
直接指针
此种方案就是栈中的引用存储的就是堆中对象的地址,直接指向堆中的对象,因此在堆中对象的存储布局中就要考虑如何存放类型数据等信息,示意图(来自《深入理解Java虚拟机》)如下:
说明:上述两种方式各有优缺点。
对于句柄方式,由于栈引用存储的是对象句柄地址,因此对象移动时(GC引发)只需要修改对应句柄指向的对象地址即可,栈中的引用不用修改;其缺点就是访问较慢,因为有两次指针定位。
对于直接指针方式,它的优点就是只有一次指针定位,访问速度快,当然句柄方式的优点也是其缺点。Sun的HotSpot虚拟机是使用直接指针的方式来访问对象的。
参考文献
《深入理解Java虚拟机:JVM高级特性与最佳实践》
- 基础回顾——Java对象创建、内存分配、访问定位概述
- JVM里java对象的创建及内存分配和访问定位
- 对象创建、内存分配、访问
- Java 内存——Java虚拟机中对象的创建、存储、访问定位。
- Java虚拟机(HotSpot)-对象:创建、内存布局、访问定位
- Java对象的创建、内存布局、访问定位
- java虚拟机——对象创建与访问概述
- 自动内存管理机制(2)——虚拟机对象的创建、内存布局和访问定位
- 对象创建、内存布局和访问定位
- 对象的创建、内存布局、访问定位
- JAVA中对象的创建、对象的内存布局、对象的访问定位
- Hotspot虚拟机--对象分配,内存布局,访问定位
- JAVA学习笔记8——面向对象概述2_内存分配
- Java中的内存区域及对象的创建、内存布局与访问定位
- java对象的创建及访问定位
- Java对象的创建、访问和定位
- Java虚拟机对象创建及其内存分配
- 对象创建,内存布局,对象的访问定位
- 线程安全的实现方法
- oracle 下载地址
- RF+Appium 压力测试:安装卸载和升降级测试
- Configuring HiveServer2 for CDH
- Problem B
- 基础回顾——Java对象创建、内存分配、访问定位概述
- 第十八章——触摸事件和UIResponder
- 【转】React Native 中组件的生命周期
- 关于linux下互斥锁和条件变量的理解
- go语言获取新浪Cookie
- Arpa's weak amphitheater and Mehrdad's valuable Hoses
- sql中drop、truncate和delete的区别
- openCv+Java实现人脸剪切
- AndroidStudio svn 上传不了.so 文件 .a文件