JVM之对象创建、对象内存布局、对象访问定位
对象创建
.png)
- 类加载过后可以直接确定一个对象的大小
- 对象栈上分配是通过逃逸分析判定、标量替换实现的,即把不存在逃逸的对象拆散,将成员变量恢复到基本类型,直接在栈上创建若干个成员变量
- 选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理 功能决定。因此,在使用Serial、ParNew等带Compact过程的收集器时,系统采用的分配算法是指针碰撞,而使用 CMS这种基于Mark-Sweep算法的收集器时,通常采用空闲列表
- 空间并发分配解决方案
- TLAB,线程私有空间分配,只有TLAB用完并分配新的TLAB时,才需要同步锁定
- CAS+失败重试保证更新操作的原子性
对象内存布局
内存布局

Klass Word(类指针):存储对象的类型指针,该指针指向它的类元数据。从JDK 1.6 update14开始,64位的JVM正式支持了-XX:+UseCompressedOops(默认开启),可以压缩指针,起到节约内存占用的作用。oop(ordinary object pointer)即普通对象指针,下列指针将压缩至32位:
- 每个Class的属性指针(静态成员变量)
- 每个对象的属性指针(对象变量)
- 普通对象数组的每个元素指针
指针压缩:
- 如果GC堆大小在4G以下,直接砍掉高32位,避免了编码解码过程(偏移量除以/乘以8)
- 如果GC堆大小在4G以上32G以下,则启用-XX:+UseCompressedOops命令
- 如果GC堆大小大于32G,压指失效,使用原来的64位
-XX:+UseCompressedClassPointers
- Java8使用Metaspace存储元数据,开启后类元信息中的指针也用32bit的Compressed版本,即Klass Word
- 依赖-XX:+UseCompressedOops
数组长度64位JVM的情况下也被压缩至32位
对齐字节:HotSpot VM的自动内存管理要求对象大小必须是8字节的整数倍,不足时需要对齐填充来补全
对象头

32位虚拟机占用32个字节,不同状态下各个比特位区间大小有变化
biased_lock:偏向锁标记,为1时表示对象启用偏向锁
age:默认情况下,并行GC的年龄阈值为15,并发GC的年龄阈值为6。由于age只有4位,所以最大值为15
identity_hashcode
- 采用延迟加载技术,只有在需要时使用System.identityHashCode(Object x)计算后写到该对象头中
- 偏向锁没有存储HashCode的地方,偏向锁期间调用System.identityHashCode(x)会造成锁升级
- 轻量级锁和重量级锁所指向的lock record或monitor都有存储HashCode的空间
- 用户自定义hashCode()方法所返回的值不存在Mark Word中,只针对identity hash code
thread:持有偏向锁的线程ID
epoch:偏向锁的时间戳
ptr_to_lock_record:轻量级锁状态下,指向栈中锁记录的指针
ptr_to_heavyweight_monitor:重量级锁状态下,指向对象监视器Monitor的指针
ClassLayout
// 引入依赖
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.11</version>
</dependency>
// 查看对象布局信息
ClassLayout layout = ClassLayout.parseInstance(new A());
System.out.println(layout.toPrintable());
可通过ClassLayout查看对象布局信息,即对象占用空间情况
对象访问定位
| 句柄访问对象 | 直接指针访问对象 |
|---|---|
![]() |
![]() |
- 句柄访问:java堆中会划分一块内存作为句柄池,线程栈中引用中存储的就是对象句柄地址。好处在于对象句柄地址固定,对象移动(垃圾回收时移动对象非常普遍)时仅改变句柄中的实例数据指针
- 直接指针访问:线程栈中引用中存储的直接就是对象地址,好处在于速度更快(Sun HotSpot使用此种)
JVM之对象创建、对象内存布局、对象访问定位的更多相关文章
- 浅谈Java虚拟机内存中的对象创建,内存布局,访问定位
参考于 深入理解Java虚拟机 这里介绍HotSpot虚拟机(自带的虚拟机) 1.对象的创建 对于程序员来说,创建对象的方法: User user1 = new User(); User user2 ...
- Java对象的创建、内存布局和访问定位
在Java运行时数据区中,我们知道了虚拟机内存的概况,本文介绍虚拟机内存中的数据的其它细节,如对象如何创建.如何布局以及如何访问. 基于实用的原则,这里以HotSpot虚拟机和常用的内存区域Java堆 ...
- JVM 专题十二:运行时数据区(七)对象的实例化内存布局与访问定位
1. 对象的实例化 1.1 创建对象的方式 new 最常见的方式 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 Class的newInstance() ...
- JVM运行时数据区--纵向补充--对象的实例化内存布局与访问定位
对象的实例化 创建对象的方式 1.new:最常见的方式(本质是构造器) 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 2.Class的newInsta ...
- 【深入理解JVM】:Java对象的创建、内存布局、访问定位
对象的创建 一个简单的创建对象语句Clazz instance = new Clazz();包含的主要过程包括了类加载检查.对象分配内存.并发处理.内存空间初始化.对象设置.执行ini方法等. 主要流 ...
- 深入理解java虚拟机(二)HotSpot Java对象创建,内存布局以及访问方式
内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的 ...
- HotSpot Java对象创建,内存布局以及访问方式
内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的 ...
- java面试-对象的创建、内存布局、访问定位
一.对象的创建 1.虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载.解析和初始化过.如果没有,那必须先执行相应的 ...
- 深入理解Java虚拟机(二)、Java对象的创建,内存布局和访问定位
对象的创建: Object obj = new Object(); 常量池中是否有Ljava.lang.Object
- 【JVM之内存与垃圾回收篇】对象实例化内存布局与访问定位
对象实例化内存布局与访问定位 从各自具体的内存分配上来讲 new 的对象放在堆中 对象所属的类型信息是放在方法区的 方法当中的局部变量放在栈空间 这 new 的对象怎么把三块粘合到一起 就是这章的内容 ...
随机推荐
- 洛谷p1198 最大数
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; in ...
- js Promise finally All In One
js Promise finally All In One finally let isLoading = true; fetch(myRequest).then(function(response) ...
- vuepress & ReferenceError: window is not defined
vuepress & ReferenceError: window is not defined bug Client Compiled successfully in 15.35s Serv ...
- how to create a style element in js (many ways)
how to create a style element in js (many ways) create style in js Constructed StyleSheets CSSStyleS ...
- Deno 1.0 & Node.js
Deno 1.0 & Node.js A secure runtime for JavaScript and TypeScript. https://deno.land/v1 https:// ...
- Flutter 使用 flare
video flare_flutter 工作示例 install dependencies: flare_flutter: ^1.5.5 assets: - assets/flr/switch_day ...
- Redis的数据结构与应用场景
一.Redis简介 Redis 是一个开源的使用 ANSI C 语言编写.遵守 BSD 协议.支持网络.可基于内存.分布式.可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API ...
- 26_ mysql数据操作语言:DELETE语句
-- DELETE语句 -- 删除10部门中,工龄超过20年的员工记录 DELETE FROM t_emp WHERE deptno=10 AND DATEDIFF(NOW(),hiredate)/3 ...
- 文件描述符(File Descriptor)简介
本文转载自文件描述符(File Descriptor)简介 导语 维基百科:文件描述符在形式上是一个非负整数.实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表.当程序打开一个 ...
- JDBC概念理解
##JDBC: 概念:Java DataBase Connectivity Java 数据库连接 Java语言操作数据库 JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则 ...

