当前位置: 首页 > news >正文

深入理解多线程(三)—— 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各个比特位区间的含义。

ObjectHead

同样,在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

相关文章:

  • 内存池原理大揭秘
  • Python3爬取英雄联盟英雄皮肤大图
  • (6)添加vue-cookie
  • win10下配置java jdk jre环境变量
  • 如何写一个日志采集工具
  • ubuntu linux下解决“no java virtual machine was found after searching the following locations:”的方法...
  • apollo-server 返回模拟数据
  • HTTP--网络协议分层,http历史(二)
  • Java编写基于netty的RPC框架
  • 使用python编写游戏修改器
  • 通过Eclipse 为java 项目生成Api 文档、JavaDoc
  • ios多个target
  • php去除html标签
  • 11月17日站立会议
  • angular搭建
  • CSS 专业技巧
  • Cumulo 的 ClojureScript 模块已经成型
  • Debian下无root权限使用Python访问Oracle
  • Docker下部署自己的LNMP工作环境
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JavaScript 一些 DOM 的知识点
  • Linux下的乱码问题
  • select2 取值 遍历 设置默认值
  • Spring核心 Bean的高级装配
  • Vue2.0 实现互斥
  • Webpack 4x 之路 ( 四 )
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 计算机在识别图像时“看到”了什么?
  • 如何设计一个微型分布式架构?
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 微信小程序:实现悬浮返回和分享按钮
  • 微信小程序--------语音识别(前端自己也能玩)
  • 一个JAVA程序员成长之路分享
  • 白色的风信子
  • 《码出高效》学习笔记与书中错误记录
  • Java总结 - String - 这篇请使劲喷我
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • ###STL(标准模板库)
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (1)常见O(n^2)排序算法解析
  • (2)STM32单片机上位机
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (转载)PyTorch代码规范最佳实践和样式指南
  • (状压dp)uva 10817 Headmaster's Headache
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET 依赖注入和配置系统
  • .NET/C# 项目如何优雅地设置条件编译符号?