java对象的内存布局分为哪几个区域
发表于:2024-11-27 作者:千家信息网编辑
千家信息网最后更新 2024年11月27日,本篇内容介绍了"java对象的内存布局分为哪几个区域"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!H
千家信息网最后更新 2024年11月27日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安全错误
数据库的锁怎样保障安全
部队网络安全个人总结报告
汕头数据链软件开发定做价格
自媒体发展数据库
数据库网上购书系统源代码
软件开发测试情况表
不能连接主数据库
网络安全中的低级错误是哪些
ibm服务器是什么东西
杭州智跃互联网科技
软件开发外包费用一览表
vfp建立数据库有什么好处
新乡良木网络技术有限公司
怎么显示cad图形数据库
数据库替换号码
世界贸易组织数据库技术与应用
网吧可以安装数据库么
华为账号显示连接不上服务器
如何修改数据库可用空间
题录文摘数据库有哪些
服务器电源管理服务能禁止吗
数据库学生会需求分析模板
迁西网络技术不二之选
学校网络技术中心
网络安全中的低级错误是哪些
网络安全及保密意识考试
国三网络技术模拟
电力营销网络安全告于段落
pcl2多人游戏服务器地址
军标软件开发计划
网络安全产品强制检测