java对象的内存布局分为哪几个区域
发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,本篇内容介绍了"java对象的内存布局分为哪几个区域"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!H
千家信息网最后更新 2024年11月23日java对象的内存布局分为哪几个区域
本篇内容介绍了"java对象的内存布局分为哪几个区域"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
HotSpot虚拟机中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。
1)对象头:包括标记字段和类型指针两部分内容(注:如果是数组对象,则包含三部分内容):
1)Mark Word(标记字段):用于存储运行时对象自身的数据。 1>占用内存大小与虚拟机位长一致,在运行期间,考虑到JVM的空间效率,Mark Word被设计成为一个非固定的数据结构,以便存储更多有效的数据。 2>存储运行时对象自身的数据: 哈希码(hash) GC分代年龄(age) 锁标识位: 01 无锁 01 偏向锁 00 轻量级锁 10 重量级锁 偏向锁标识位(biased_lock) 0 无锁 1 偏向锁 偏向线程ID(JavaThread*) 偏向时间戳(epoch) 说明:锁标识位、偏向锁标识位、偏向线程ID等的具体实现均是在monitor对象中完成的。(源码中的ObjectMonitor对象) 3>Mark Word里存储的数据会随着锁标志位的变化而变化,即不同的锁状态,存储着不同的数据: 锁状态 存储内容 锁标识位 偏向锁标识位(是否是偏向锁) -------- ------------------------------ -------- -------- 无锁状态 哈希码、GC分代年龄 01 0 偏向锁 线程ID、偏向时间戳、GC分代年龄 01 1 轻量级锁 指向栈中锁记录的指针 00 无 重量级锁 指向monitor的指针 10 无 GC标记 无 11 无2)Class Metadata Address(类型指针):指向对象的类元数据(方法区的Class数据),虚拟机通过这个指针确定该对象是哪个类的实例。3)如果对象是数组类型,则对象头中还存储着数组的长度。
2)实例数据:存放类的属性数据信息,包括父类的属性信息。
3)对齐填充:由于虚拟机要求对象起始地址必须是8字节的整数倍,填充数据不是必须存在的,仅仅是为了字节对齐。
4)使用JOL(Java Object Layout)工具查看java对象的内存布局:
maven依赖:代码: public class TestClassLayout { public static void main(String[] args) { TestClass[] testClassObj = new TestClass[5]; // 查看对象内存布局 System.out.println(ClassLayout.parseInstance(testClassObj).toPrintable()); } } 结果: 1 [Lcom.jxn.test.TestClass; object internals: 2 OFFSET SIZE TYPE DESCRIPTION VALUE 3 0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) 4 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 5 8 4 (object header) 82 c1 00 f8 (10000010 11000001 00000000 11111000) (-134168190) 6 12 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5) 7 16 20 com.jxn.test.TestClass TestClass;. org.openjdk.jol jol-core 0.14 N/A 8 36 4 (loss due to the next object alignment) 9 Instance size: 40 bytes 10 Space losses: 0 bytes internal + 4 bytes external = 4 bytes total 对象头: 第3行+第4行: Mark Word(标记字段) 第5行: 类型指针 第6行: 数组长度 实例数据: 第7行: 数组中存储了5个TestClass对象的引用(开启指针压缩后,类型引用占4个字节),故占用5*4=20个字节。 对齐填充: 第8行: 对象头+实例数据 占用的内存为36字节(不是8的整数倍),故需要4字节的对齐填充。 对象占用的总空间: 第9行 内存浪费的总空间: 第10行: 对齐填充消耗了4个字节。 说明:若数组的长度改为6,则 对象头+实例数据 占用的内存为40字节(8的整数倍),故不会出现对齐填充: [Lcom.jxn.test.TestClass; object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 82 c1 00 f8 (10000010 11000001 00000000 11111000) (-134168190) 12 4 (object header) 06 00 00 00 (00000110 00000000 00000000 00000000) (6) 16 24 com.jxn.test.TestClass TestClass;. N/A Instance size: 40 bytes Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
5)hotspot/src/share/vm/oops/markOop.hpp 源码中的说明:
// The markOop describes the header of an object.//// Note that the mark is not a real oop but just a word.// It is placed in the oop hierarchy for historical reasons.//// Bit-format of an object header (most significant first, big endian layout below)://// 32 bits:// --------// hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object)// JavaThread*:23 epoch:2 age:4 biased_lock:1 lock:2 (biased object)// size:32 ------------------------------------------>| (CMS free block)// PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)//// 64 bits:// --------// unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object)// JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object)// PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)// size:64 ----------------------------------------------------->| (CMS free block)//// unused:25 hash:31 -->| cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && normal object)// JavaThread*:54 epoch:2 cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && biased object)// narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)// unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)//// - hash contains the identity hash value: largest value is// 31 bits, see os::random(). Also, 64-bit vm's require// a hash value no bigger than 32 bits because they will not// properly generate a mask larger than that: see library_call.cpp// and c1_CodePatterns_sparc.cpp.//// - the biased lock pattern is used to bias a lock toward a given// thread. When this pattern is set in the low three bits, the lock// is either biased toward a given thread or "anonymously" biased,// indicating that it is possible for it to be biased. When the// lock is biased toward a given thread, locking and unlocking can// be performed by that thread without using atomic operations.// When a lock's bias is revoked, it reverts back to the normal// locking scheme described below.//// Note that we are overloading the meaning of the "unlocked" state// of the header. Because we steal a bit from the age we can// guarantee that the bias pattern will never be seen for a truly// unlocked object.//// Note also that the biased state contains the age bits normally// contained in the object header. Large increases in scavenge// times were seen when these bits were absent and an arbitrary age// assigned to all biased objects, because they tended to consume a// significant fraction of the eden semispaces and were not// promoted promptly, causing an increase in the amount of copying// performed. The runtime system aligns all JavaThread* pointers to// a very large value (currently 128 bytes (32bVM) or 256 bytes (64bVM))// to make room for the age bits & the epoch bits (used in support of// biased locking), and for the CMS "freeness" bit in the 64bVM (+COOPs).//// [JavaThread* | epoch | age | 1 | 01] lock is biased toward given thread// [0 | epoch | age | 1 | 01] lock is anonymously biased//// - the two lock bits are used to describe three states: locked/unlocked and monitor.//// [ptr | 00] locked ptr points to real header on stack// [header | 0 | 01] unlocked regular object header// [ptr | 10] monitor inflated lock (header is wapped out)// [ptr | 11] marked used by markSweep to mark an object not valid at any other time//// We assume that stack/thread pointers have the lowest two bits cleared.
"java对象的内存布局分为哪几个区域"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
对象
数据
内存
字节
存储
指针
实例
数组
标识
布局
内容
类型
标记
区域
字段
年龄
指向
整数
更多
状态
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
交换机可以接几个服务器
汉南区电商网络安全维护要多少钱
互联网科技空间折叠
鸿蒙概念网络安全股票一览表
血液系统肿瘤数据库
数据库 概念模式
数据库应用技术答案郑州大学
2020正式服服务器人口
派盾网络安全
数据库加载内容缺少
网络安全招投标
数据库 材料建弱实体集
erp分销软件开发公司
网络安全知识与工作结合
滨州软件开发
互联网与科技文章
七台河网络安全周活动
苏州回收服务器
天津域速通网络技术有限公司
违反网络安全法的处理措施有
小程序买什么数据库
数据库如何快速造多表数据
数据库数组更新sql
未来之役那个服务器老外多
保护网络安全宣传活动总结
数据库 材料建弱实体集
华为数通网络安全岗
苏州营销软件开发
深圳销售软件开发订制
数据库缓存在哪里加