深入理解多线程(三)—— Java的对象头
上一篇文章中我们从HotSpot的源码入手,介绍了Java的对象模型。这一篇文章在上一篇文章的基础上再来介绍一下Java的对象头。主要介绍一下对象头的作用,结构以及他和锁的关系。
Java对象模型回顾与勘误
在上一篇文章中,关于对象头的部分描述有误,我已经在我博客的文章中就行修正 。这里再重新表述一下。
每一个Java类,在被JVM加载的时候,JVM会给这个类创建一个instanceKlass
,保存在方法区,用来在JVM层表示该Java类。当我们在Java代码中,使用new创建一个对象的时候,JVM会创建一个instanceOopDesc
对象,这个对象中包含了对象头以及实例数据。
这里提到的对象头到底是什么呢?
class oopDesc {
friend class VMStructs;
private:
volatile markOop _mark;
union _metadata {
wideKlassOop _klass;
narrowOop _compressed_klass;
} _metadata;
}
上面代码中的_mark
和_metadata
其实就是对象头的定义。关于_metadata
之前就介绍过,这里不再赘述。由于这个专题主要想介绍和JAVA并发相关的知识,所以本文展开介绍一下_mark
,即mark word。
对象头信息是与对象自身定义的数据无关的额外存储成本,考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。
对markword的设计方式上,非常像网络协议报文头:将mark word划分为多个比特位区间,并在不同的对象状态下赋予比特位不同的含义。下图描述了在32位虚拟机上,在对象不同状态时 mark word各个比特位区间的含义。
同样,在HotSpot的源码中我们可以找到关于对象头对象的定义,会一一印证上图的描述。对应与markOop.hpp类。
enum { age_bits = 4,
lock_bits = 2,
biased_lock_bits = 1,
max_hash_bits = BitsPerWord - age_bits - lock_bits - biased_lock_bits,
hash_bits = max_hash_bits > 31 ? 31 : max_hash_bits,
cms_bits = LP64_ONLY(1) NOT_LP64(0),
epoch_bits = 2
};
从上面的枚举定义中可以看出,对象头中主要包含了GC分代年龄、锁状态标记、哈希码、epoch等信息。
从上图中可以看出,对象的状态一共有五种,分别是无锁态、轻量级锁、重量级锁、GC标记和偏向锁。在32位的虚拟机中有两个Bits是用来存储锁的标记为的,但是我们都知道,两个bits最多只能表示四种状态:00、01、10、11,那么第五种状态如何表示呢 ,就要额外依赖1Bit的空间,使用0和1来区分。
在32位的HotSpot虚拟机 中对象未被锁定的状态下,Mark Word的32个Bits空间中的25Bits用于存储对象哈希码(HashCode),4Bits用于存储对象分代年龄,2Bits用于存储锁标志位,1Bit固定为0,表示非偏向锁。
markOop.hpp类中有关于对象状态的定义:
enum { locked_value = 0,
unlocked_value = 1,
monitor_value = 2,
marked_value = 3,
biased_lock_pattern = 5
};
简单翻译一下:
locked_value(00) = 0
unlocked_value(01) = 1
monitor_value(10) = 2
marked_value(11) = 3
biased_lock_pattern(101) = 5
关于为什么要定义这么多状态,上面提到的轻量级锁、重量级锁、偏向锁以及他们之前的关系,会在下一篇文章中重点阐述,敬请期待。
from:https://www.hollischuang.com/archives/1953
深入理解多线程(三)—— Java的对象头的更多相关文章
- 多线程(三) java中线程的简单使用
java中,启动线程通常是通过Thread或其子类通过调用start()方法启动. 常见使用线程有两种:实现Runnable接口和继承Thread.而继承Thread亦或使用TimerTask其底层依 ...
- java对象头信息和三种锁的性能对比
java头的信息分析 首先为什么我要去研究java的对象头呢? 这里截取一张hotspot的源码当中的注释 这张图换成可读的表格如下 |-------------------------------- ...
- 深入理解多线程(五)—— Java虚拟机的锁优化技术
本文是<深入理解多线程>的第五篇文章,前面几篇文章中我们从synchronized的实现原理开始,一直介绍到了Monitor的实现原理. 前情提要 通过前面几篇文章,我们已经知道: 1.同 ...
- 深入理解多线程(二)—— Java的对象模型
上一篇文章中简单介绍过synchronized关键字的方式,其中,同步代码块使用monitorenter和monitorexit两个指令实现,同步方法使用ACC_SYNCHRONIZED标记符实现.后 ...
- JAVA对象头详解(含32位虚拟机与64位虚拟机)
为什么要学习Java对象头 学习Java对象头主要是为了解synchronized底层原理,synchronized锁升级过程,Java并发编程等. JAVA对象头 由于Java面向对象的思想,在JV ...
- java 多线程三
java 多线程一 java 多线程二 java 多线程三 java 多线程四 注意到 java 多线程一 中 MyThread2 运行结果出现0.-1,那是因为在操作共享数据时没有加锁导致. 加锁的 ...
- JAVA并发-对象方法wait
最简单的东西,往往包含了最复杂的实现,因为需要为上层的存在提供一个稳定的基础,Object作为java中所有对象的基类,其存在的价值不言而喻,其中wait和notify方法的实现多线程协作提供了保证. ...
- 并发王者课-青铜5:一探究竟-如何从synchronized理解Java对象头中的锁
在前面的文章<青铜4:synchronized用法初体验>中,我们已经提到锁的概念,并指出synchronized是锁机制的一种实现.可是,这么说未免太过抽象,你可能无法直观地理解锁究竟是 ...
- 从零开始学习Java多线程(三)
本文主要对Java多线程同步与通信以及相关锁的介绍. 1 .Java多线程安全问题 Java多线程安全问题是实现并发最大的问题,可以说多线程开发其实就是围绕多线程安全问题开发,涉及之深,不是简简单单一 ...
随机推荐
- Linux 获取目录中最后一个文件的名字
find /application/docker_hub/logs/fof1private/amount_dev -type l | xargs basename
- 记在VMware虚拟机中对网站进行性能压力测试的经历
由于本次测试,仅仅是对静态网站首页进行的测试,所以没有涉及到MySQL数据库的性能监测 服务器基本配置 webbench测试工具 Linux上一款优秀的web性能压力测试工具.webbench最多可以 ...
- js数组遍历some、foreach、map、filter、every、lastIndexOf、indexOf对比
1. [...].some(ck)函数 对数组中每个元素执行一次ck函数,知道某个元素返回true,则直接返回true.如果都返回false,则返回false 检查整个数组中是否有满足ck函数的元素. ...
- 循序渐进学.Net Core Web Api开发系列【0】:序言与目录
一.序言 我大约在2003年时候开始接触到.NET,最初在.NET framework 1.1版本下写过代码,曾经做过WinForm和ASP.NET开发.大约在2010年的时候转型JAVA环境,这么多 ...
- IO写 PrintWriter
private static final String FILENAME = "c:\\temp\\out.txt"; PrintWriter pw = null; try { p ...
- vue-video-player的使用总结
由于公司的项目是网上教育的,像网易云课堂那种教育网站,因而会有很多课程需要在线观看的,所以视频插件是必不可少的. 由于我用vue开发项目,所以找视频插件也找和vue贴近的.最后选择了vue-video ...
- 单源最短路模板 + hdu - 2544
Floyd Floyd 本质上类似一种动态规划,dp [ i ] [ j ] = dp [ i ] [ k ] + dp[ k ] [ j ]. /** * Night gathers, and no ...
- 【面试虐菜】—— JAVA面试题(1)
今天参加笔试,里面有设计模式,和一些基础题! 印象最深的是:什么不是Object的函数,我蒙的finalize,哎,无知! 还问了,接口与抽象类的不同,还有多线程的实现方式!下面基本都有. 另外还问了 ...
- CentOS启动OpenVPN报错:Failed to start OpenVPN Robust And Highly Flexible Tunneling Application On server.
tailf /var/log/openvpn.log 查看日志,里面有最详细的错误解说. 参考: https://forums.openvpn.net/viewtopic.php?t=21561
- layer.confirm 询问框 的层遮盖
function admin_del(obj) { layer.confirm('确认要重启吗?', { btn : [ '确定', '取消' ]//按钮 }, function(index) { l ...