JVM对象头中的锁信息机制详解
JVM对象头中的锁信息机制详解
Java中的对象锁机制是高性能并发的基石,而这一切的底层实现都离不开对象头中的 Mark Word 字段。本文将系统梳理JVM对象头中锁信息的存储与演化机制,解析锁升级与批量重偏向优化原理,并通过JOL工具实战验证对象头的实际变化。
一、对象头与Mark Word结构
每个Java对象在内存中的布局如下(64位JVM,开启指针压缩):
字段 | 大小 | 说明 |
---|---|---|
Mark Word | 64 bits | 存储锁信息、哈希码、GC年龄等 |
Klass Pointer | 32 bits | 指向类元数据 |
Array Length | 32 bits | 仅数组对象,记录长度 |
Mark Word的动态结构
Mark Word 的内容根据锁状态动态变化,主要分为以下几种:
状态 | 标志位 | 存储内容(64位) | 适用场景 |
---|---|---|---|
无锁 | 01 | 哈希码31bit、GC年龄4bit、未用位、偏向位 | 无竞争 |
偏向锁 | 01 | 线程ID54bit、epoch2bit、GC年龄4bit、偏向位 | 单线程独占 |
轻量级锁 | 00 | 指向栈中锁记录的指针62bit | 低并发、短同步块 |
重量级锁 | 10 | 指向Monitor(OS互斥量)指针62bit | 高并发、长耗时临界区 |
GC标记 | 11 | 空值,用于GC标记 | GC期间 |
二、锁状态的升级与降级机制
JVM采用不可逆锁升级策略,根据竞争强度动态提升锁级别,避免频繁的锁降级带来的性能问题。
各锁状态简析
- 偏向锁:第一次线程访问时,Mark Word“贴标签”记录线程ID,后续该线程进入同步块无需CAS,极致优化无竞争场景。
- 轻量级锁:当有第二个线程竞争时,通过CAS将Mark Word复制到线程栈中的锁记录(Lock Record),自旋尝试获取锁。
- 重量级锁:自旋失败或竞争激烈时,升级为重量级锁,对象头指向Monitor,线程进入阻塞队列,由操作系统调度。
锁升级示例
public class Counter {private int count = 0;private final Object lock = new Object();public void increment() {synchronized(lock) {count++;}}public static void main(String[] args) {Counter counter = new Counter();// 1. 单线程独占(偏向锁)IntStream.range(0, 100).forEach(i -> counter.increment());// 2. 两线程交替访问(轻量级锁)new Thread(() -> IntStream.range(0, 100).forEach(i -> counter.increment())).start();new Thread(() -> IntStream.range(0, 100).forEach(i -> counter.increment())).start();// 3. 多线程竞争(重量级锁)ExecutorService pool = Executors.newFixedThreadPool(10);IntStream.range(0, 1000).forEach(i -> pool.submit(counter::increment));}
}
三、偏向锁批量重偏向机制(epoch优化)
1. 触发条件
- 某个类的对象被不同线程撤销偏向锁超过阈值(默认20次,可用
-XX:BiasedLockingBulkRebiasThreshold
调整)。 - 达到更高阈值(默认40次,
-XX:BiasedLockingBulkRevokeThreshold
)后,彻底禁用该类偏向锁。
2. epoch机制实现
- 每个类维护一个全局epoch值,对象头Mark Word中记录当前epoch副本。
- 发生批量重偏向时,类的epoch+1,无需遍历对象头一一CAS,只需访问时对比epoch。
- 访问对象时,若对象头epoch与类epoch不一致,则允许重新偏向新线程。
示例代码
public class BulkRebiasDemo {public static void main(String[] args) {List<Object> list = new ArrayList<>();// 阶段1:A线程创建并偏向100个对象for (int i = 0; i < 100; i++) {Object obj = new Object();synchronized(obj) {} // 偏向线程Alist.add(obj);}// 阶段2:B线程访问这些对象new Thread(() -> {for (Object obj : list) {synchronized(obj) {// 前20次撤销,后续批量重偏向}}}).start();}
}
3. 优势
- 批量操作:O(N)次CAS变为O(1)全局epoch更新,大幅降低锁撤销开销。
- 性能提升:高并发下减少CPU颠簸,提升吞吐量。
四、JVM对象头结构与验证
1. JOL工具实战
JOL (Java Object Layout) 可直接查看对象头布局:
Maven依赖:
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.17</version>
</dependency>
验证代码:
public static void main(String[] args) {Object obj = new Object();System.out.println(ClassLayout.parseInstance(obj).toPrintable());int[] arr = new int[3];System.out.println(ClassLayout.parseInstance(arr).toPrintable());
}
输出示例(64位JVM,压缩指针):
java.lang.Object object internals:OFFSET SIZE TYPE DESCRIPTION0 4 (object header) # Mark Word4 4 (object header) # 类型指针8 4 (object header) # 数组长度(数组对象)12 4 (loss due to...)[I object internals:OFFSET SIZE TYPE DESCRIPTION0 4 (object header) # Mark Word4 4 (object header) # 类型指针8 4 (object header) # 数组长度=312 12 int [I.<elements> # 数组元素24 4 (loss due to...)
2. 锁状态变化观测
Object lock = new Object();
System.out.println("初始状态:" + ClassLayout.parseInstance(lock).toPrintable());synchronized(lock) {System.out.println("加锁状态:" + ClassLayout.parseInstance(lock).toPrintable());
}
- 关注Mark Word最后2~3位:
01
(无锁/偏向锁)、00
(轻量级锁)、10
(重量级锁)
五、性能影响与优化建议
锁类型 | 适用场景 | 性能特点 | 优化建议 |
---|---|---|---|
偏向锁 | 单线程独占 | 零额外开销 | -XX:BiasedLockingStartupDelay=0 |
轻量级锁 | 低并发短同步块 | 自旋消耗CPU | 控制自旋次数(-XX:PreBlockSpin) |
重量级锁 | 高并发/长临界区 | 上下文切换开销大 | 减少同步块粒度 |
批量重偏向 | 高并发多线程访问 | O(1)批量优化,减少CAS | 合理设置阈值,避免频繁撤销 |
六、总结
- 对象头中的Mark Word是Java对象锁实现的核心,能够动态存储锁状态、线程ID、指针等信息。
- 锁升级不可逆,保证了线程安全和性能的平衡。
- 批量重偏向机制通过epoch优化,将大量CAS操作降为常数级epoch对比,极大提升高并发下的锁撤销效率。
- 借助JOL工具,开发者可直观观测对象头在不同锁状态下的变化,为并发调优提供有力支撑。
理解JVM对象头中的锁机制,有助于我们写出更高效、更具可预测性的并发代码。欢迎大家用JOL实战,深度探索Java对象的“内在世界”!
参考资料:
- Java官方JVM文档
- JOL项目主页
- 深入理解Java虚拟机
相关文章:
JVM对象头中的锁信息机制详解
JVM对象头中的锁信息机制详解 Java中的对象锁机制是高性能并发的基石,而这一切的底层实现都离不开对象头中的 Mark Word 字段。本文将系统梳理JVM对象头中锁信息的存储与演化机制,解析锁升级与批量重偏向优化原理,并通过JOL工具实战验证对象…...
需要低调使用的网盘小工具
周末总是过得飞快,转眼间周一又要来临。今天就不多说,直接给大家分享一款实用的小软件! 软件介绍 今天给大家带来一款网盘转存工具——BaiduPanFilesTransfers。 这款工具是某知名网盘的批量转存利器。软件作者已经编写了一份非常详细的说明…...
js fetch流式请求 AI动态生成文本,实现逐字生成渲染效果
开启流式请求:向后端接口发起普通的 fetch,它会返回一个包含 ReadableStream 的 Response 对象获取流式读取器:调用 response.body.getReader() 获取一个 ReadableStreamDefaultReader 实例循环读取数据块:在 while(true) 循环或 …...
软考教材重点内容 信息安全工程师 第24章 工控安全需求分析与安全保护工程
24.1.1 工业控制系统概念及组成 工业控制系统是由各种控制组件、监测组件、数据处理与展示组件共同构成的对工业生产过程进行控制和监控的业务流程管控系统。工业控制系统通常简称工控系统(ICS)。工控系统通常分为离散制造类和过程控制类两大类,控制系统包括 SCADA…...
BGP基础实验
一、配置思路 AS200 内部路由由 OSPF 负责,使 AR2 ~ AR5 内部环回地址可达。 各 AS 之间通过 BGP 实现跨域路由互通。 通过 import-route ospf 语句将 OSPF 路由导入 BGP,再由 BGP 向外通告。 使用 network 命令通告本地环回地址。 AR1 <Huawei…...
遭遇DDoS攻击为什么不能反击回去?
遭遇DDoS(分布式拒绝服务)攻击时,不能直接“反击回去”的原因涉及技术、法律、道德和实际操作的多个层面。以下是详细分析: 1. 技术难题:难以定位真正的攻击者 分布式攻击源:DDoS攻击的特点是流量来自全球各…...
专题二:二叉树的深度搜索(二叉树剪枝)
以leetcode814题为例 题目分析: 也就是当你的子树全为0的时候就可以剪掉 算法原理分析: 首先分析问题,你子树全为0的时候才可以干掉,我们可以设递归到某一层的时候如何处理 然后抽象出三个核心问题 也就是假设我们递归到第2层…...
服务器共享文件夹如何实现外网访问
一、远程访问共享文件需求 有些企业在内网服务器上存储了很多重要工作文件,这些文件共享后需要在外网被员工访问 快解析帮助用户远程访问企业内网服务器共享文件夹 二、快解析实现远程共享文件夹的方法 下面简单介绍一下通过内网穿透快解析实现自己服务器上的共享…...
git|gitee仓库同步到github
参考:一次提交更新两个仓库,Get 更优雅的 GitHub/Gitee 仓库镜像同步 文章目录 进入需要使用镜像功能的仓库,进入「管理」找到「仓库镜像管理」选项,点击「添加镜像」按钮绑定github绑定成功后再次点击添加镜像如何申请 GitHub 私…...
1.Redis-key的基本命令
(一)Redis的基本类型 String,List,Set,Hash,Zset 三种特殊类型:geospatial(地理空间数据)、hyperloglog[基数估算(去重计数)]、bitmaps(位图&…...
配置Hadoop集群环境-使用脚本命令实现集群文件同步
在 Hadoop 集群环境中,确保各节点配置文件一致至关重要。以下是使用 rsync 结合 SSH 实现集群文件同步的脚本方案,支持批量同步文件到所有节点: 1. 前提条件 所有节点已配置 SSH 免密登录主节点(NameNode)能通过主机…...
搭建高可用及负载均衡的Redis
搭建高可用及负载均衡的Redis系统是确保数据存储和访问高效且可靠的关键。本文将详细介绍如何配置高可用的Redis集群,并通过负载均衡实现性能优化。 高可用Redis架构设计 高可用性是指系统在部分组件失效时仍能继续运行。对于Redis,高可用架构通常包括…...
Hepatology | 南京鼓楼医院余德才团队:从「无药可用」到「精准打击」!肝癌脂肪代谢分型让3类患者各有生路!
文章标题:Multiomics identifies metabolic subtypes based on fatty acid degradation allocating personalized treatment in hepatocellular carcinoma 发表期刊:Hepatology 影响因子:12.9 客户单位:南京市鼓楼医院 百趣提…...
【日撸 Java 三百行】Day 11(顺序表(一))
目录 Day 11:顺序表(一) 一、关于顺序表 二、关于面向对象 三、代码模块分析 1. 顺序表的属性 2. 顺序表的方法 四、代码及测试 拓展: 小结 Day 11:顺序表(一) Task: 在《数…...
配置集群-日志聚集操作
日志聚集是指将分布式集群中各个节点上的应用程序日志收集并汇总到一个集中的位置,方便后续的查看、分析和管理。在 Hadoop 和 Spark 集群中,日志聚集是一项重要的功能,下面分别介绍如何在这两个集群中配置日志聚集操作。 Hadoop 集群日志聚…...
node版本.node版本、npm版本和pnpm版本对应
报错: ERR_PNPM_META_FETCH_FAIL GET https://registry.npmmirror.com/rollup: Value of "this" must be of type URLSearchParams node版本 Node.js — Node.js Releases node和pnpm对应关系 Installation | pnpm 参考 NVM管理node版本.node版本、…...
电商物流管理优化:从网络重构到成本管控的全链路解析
大家好,我是沛哥儿。作为电商行业,我始终认为物流是电商体验的“最后一公里”,更是成本控制的核心战场。随着行业竞争加剧,如何通过物流网络优化实现降本增效,已成为电商企业的必修课。本文将从物流网络的各个环节切入…...
Java学习手册:客户端负载均衡
一、客户端负载均衡的概念 客户端负载均衡是指在客户端应用程序中,根据一定的算法和策略,将请求分发到多个服务实例上。与服务端负载均衡不同,客户端负载均衡不需要通过专门的负载均衡设备或服务,而是直接在客户端进行请求的分发…...
E+H流量计与Profibus DP主站转Modbus RTU/TCP网关通讯
EH流量计与Profibus DP主站转Modbus RTU/TCP网关通讯 随着工业自动化的不断发展,各种不同品牌、型号的设备需要进行数据交互和通信。在实际应用中,EH流量计作为一种常用的流量测量设备,常常需要与其他设备进行连接和通信。而Profibus DP是一…...
mysql配置输入错误密码3次后锁定60s
mysql配置输入错误密码3次后锁定60s 1、安装插件 INSTALL PLUGIN CONNECTION_CONTROL SONAME connection_control.so; INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME connection_control.so; 2、验证是否安装成功 SHOW VARIABLES LIKE connection_control…...
首屏优化,webpack插件用于给html中js自动添加异步加载属性
因为要使用cheerio库,需要安装 npm安装 npm install cheerio --save-dev或使用 yarn安装 yarn add cheerio --dev创建async-script-webpack-plugin.js const cheerio require(cheerio);class AsyncScriptWebpackPlugin {constructor(options {}) {this.options …...
SQLite 数据库常见问题及解决方法
一、数据库文件锁定问题 1. 问题表现 在多线程或多进程环境下访问 SQLite 数据库时,常常会出现数据库文件被锁定的情况。当一个进程对数据库执行写操作时,其他进程的读写操作都会被阻塞,导致应用程序出现卡顿甚至无响应。比如在移动应用开发…...
day 23
机器学习管道 pipeline 一般通用pipeline的实现流程: 1.构建多个转换器(transformer),来实现对特征的预处理 2.构建 ColumnTransformer,将不同的预处理应用于不同的列子集,构造一个完备的转化器 3.构建…...
MATLAB复制Excel数据到指定区域
Matlab中如何将Excel表中的265-528行F-AA列数据复制到1-263行AE-AZ中 版本:MatlabR2018b clc; clear; %旧Excel文件名 oldFile ; %新Excel文件名 newFile ; % 工作表名称(旧表和新表一致) sheetName Sheet1; % 旧文件中待复制的数据范…...
docker配置mysql主从同步
1. 创建Docker网络 docker network create mysql-network 2. 创建数据卷 docker volume create mysql-master-volume docker volume create mysql-slave-volume 3. 准备MySQL配置文件 主库配置 (master.cnf) [mysqld] server-id1 log-binmysql-bin binlog_formatROW gtid_mo…...
机动车授权签字人备考考试题库及答案
一、单选题 13、《中华人民共和国大气污染防治法》规定,进口、销售超过污染物排放标准的机动车、非道路移动机械的,由县级以上人民政府( )按照职责没收违法所得,并处货值金额一倍以上三倍以下的罚款,没收销毁无法达到污染物排放标准的机动车、非道路移动机械。 A、生态…...
WebGL图形编程实战【6】:性能优化 × 调试工具与技巧精讲
调试工具 NVIDIA Nsight Systems NVIDIA Nsight Systems 这个工具帮助开发者深入了解应用程序在CPU、GPU 和网络通信等各个层面的运行情况,从而有效地识别性能瓶颈并进行优化 WebGL-Inspector 插件的地址在这:WebGL-Inspector chrome插件 但是在这里…...
69、微服务保姆教程(十二)容器化与云原生
容器化与云原生 在微服务架构中,容器化和云原生技术是将应用程序部署到生产环境的核心技术。通过容器化技术,可以将应用程序及其依赖项打包成一个容器镜像,确保在任何环境中都能一致运行。而云原生技术则通过自动化的容器编排系统(如 Kubernetes),实现应用的动态扩展、自…...
CSS3(BFC)
CSS3(BFC) 1、什么是BFC W3C 上对 BFC 的定义: 原文:Floats, absolutely positioned elements, block containers (such as inline-blocks, table- cells, and table-captions) that are not block boxes, and block boxes with ‘overflow’ other tha…...
OrangePi Zero 3学习笔记(Android篇)7 - ftdi_sio
目录 1. 内核配置 2. SPI设备 3. 验证 这部分需要基于之前修改的ftdi_sio驱动,增加MPSSE部分的代码。 1. 内核配置 一般默认USB转串口是关闭的,所以需要配置打开。在源代码根目录下执行: ./longan/build.sh menuconfig 菜单进入顺序&a…...
自适应蒙特卡洛定位-AMCL
自适应蒙特卡洛定位,简称AMCL,主要提供定位功能并以/tf形式输出 蒙特卡洛算法的基本思想:当所要求的问题是某种事件出现的概率或者是某个变量的期望值时,它们可以通过某种"试验"的方法,得到这种事件出现的概…...
用python清除PDF文件中的水印(Adobe Acrobat 无法删除)
学校老师发的资料,有时候会带水印,有点强迫症的都想给它去掉。用Adobe Acrobat试了下,检测不到水印,无法删除!分析发现原来这类PDF文件是用word编辑的,其中的水印是加在了页眉中! 自己动手想办法…...
bootstrap自助(抽样)法
一,概念 一言以蔽之:从训练集中有放回的均匀抽样——》本质就是有放回抽样; 自助法(bootstrap)是一种通过从数据集中重复抽样来估计统计量分布的非参数方法。它可用于构建假设检验,当对参数模型的假设存在…...
综合实验二之删除/boot目录,进行系统修复
实验三、删除/boot目录,进行系统修复 在 Linux 系统中,/boot 目录是一个至关重要的系统目录,主要用于存放系统启动时所需的核心文件和配置信息。 /boot 目录的主要作用: 存放内核文件(Kernel) vmlinuz&…...
postgresql主从集群一键搭建脚本分享
脚本1: cat pg_ms_install.sh #!/bin/bash # 基础环境配置(保持不变) setenforce 0 >/dev/null 2>&1 || true sed -i "s/SELINUXenforcing/SELINUXdisabled/" /etc/selinux/config systemctl stop firewalld >/dev/n…...
融合一致性与差异性约束的光场深度估计
摘要:光场图像深度估计是光场三维重建、目标检测、跟踪等应用中十分关键的技术。虽然光场图像的重聚焦特性为深度估计提供了非常有用的信息,但是在处理遮挡区域、边缘区域、噪声干扰等情况时,光场图像深度估计仍然存在很大的挑战。因此&#…...
转运机器人可以绕障吗?
在工业物流场景中,障碍物动态分布、路径突发拥堵是常态。传统AGV依赖固定轨道或磁条,面对复杂环境时往往“束手无策”。转运机器人可以绕障吗?富唯智能用技术创新给出答案——搭载激光SLAM导航与多传感器融合技术,其转运机器人不仅…...
【Web前端开发】CSS基础
2.CSS 2.1CSS概念 CSS是一组样式设置的规则,称为层叠样式表,用于控制页面的外观样式。 使用CSS能够对网页中元素位置的排版进行像素控制,实现美化页面的效果,也能够做到页面的样式和结构分离。 2.2基本语法 通常都是ÿ…...
【物流开单专用软件】佳易王物流管理系统:常见的物流信息系统以及软件程序实操教程 #物流软件定制#物流软件开发#物流软件推荐
一、概述 软件试用版资源文件下载方法: 【进入头像主页第一篇文章最后 卡片按钮 可点击了解详细资料 或左上角本博客主页 右侧按钮了解具体资料信息】 本实例以 佳易王物流管理系统 为例说明,其他版本可参考本实例。试用版软件资源可到文章最…...
力扣-94.二叉树的中序遍历
题目描述 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 class Solution { public:void inorder(TreeNode* root, vector<int>& res){//C这里&一定要加if(!root)return;inorder(root->left,res);res.push_back(root->val);inorder(ro…...
对基于再生龙制作的Linux系统的硬盘进行扩容
背景 公司一个仪器产品是基于x86核心板开发的,因此制作系统镜像时用的再生龙软件,好处是制作的系统镜像比ARM平台那种raw image小很多,缺点是操作有点麻烦。 最近客户反馈512GB的SSD硬盘容量不够,因此公司决定升级成1TB的&#x…...
Spring Boot 注解详细解析:解锁高效开发的密钥
一、引言 Spring Boot 以其快速开发、自动配置等特性,成为构建 Java 应用程序的热门框架。而注解在 Spring Boot 中扮演着至关重要的角色,它们如同魔法指令,简化了配置流程,增强了代码的可读性与可维护性。本文将深入剖析 Spring…...
【速写】KV-cache与解码的再探讨(以束搜索实现为例)
文章目录 1 Beam Search 解码算法实现2 实现带KV Cache的Beam Search解码3 关于在带kv-cache的情况下的use_cache参数 1 Beam Search 解码算法实现 下面是一个使用PyTorch实现的beam search解码算法: 几个小细节: 束搜索可以加入length_penalty&#…...
ElasticSearch聚合操作案例
1、根据color分组统计销售数量 只执行聚合分组,不做复杂的聚合统计。在ES中最基础的聚合为terms,相当于 SQL中的count。 在ES中默认为分组数据做排序,使用的是doc_count数据执行降序排列。可以使用 _key元数据,根据分组后的字段数…...
微信小程序单双周选择排序有效果图
效果图 .wxml <view class"group-box"><label class"radio" wx:for"{{[单周,双周,全选]}}" wx:key"index" bind:tap"radioChange"data-index"{{index}}"><radio checked"{{index zcTem.ind…...
保持Word中插入图片的清晰度
大家有没有遇到这个问题,原本绘制的高清晰度图片,插入word后就变模糊了。先说原因,word默认启动了自动压缩图片功能,分享一下如何关闭这项功能,保持Word中插入图片的清晰度。 ①在Word文档中,点击左上角的…...
Matlab 基于GUI的汽车巡航模糊pid控制
1、内容简介 Matlab 225-基于GUI的汽车巡航模糊pid控制 可以交流、咨询、答疑 2、内容说明 略 依据比例—积分—微分控制的基本原理,我们利用MATLAB软件中SMULINK建立一个简单的PID控制器模型,利用这个模型在模糊控制过程中对PID控制参数进行在线的实时…...
(网络)应用层协议-HTTPS
1.HTTPS是什么? HTTPS是应用层的一种协议,是在HTTP的基础上进行了加密层的处理。 HTTP协议的内容都是按照文本的形式进行传输的,所以呢就很容易被别人知道传输的是什么。 我们在了解了TCP/IP之后是知道我们的数据在传输的过程中是通过路由器进…...
Browserless 快速上手
要将你提供的 HTML 模板和数据结构转换为可以用于 Browserless /pdf 接口的 JSON 请求体(且能正确渲染为 PDF),需要满足以下几点: ✅ 最终目标格式(这是能用的格式): json 复制编辑 { "h…...
JWT的介绍与在Fastapi框架中的应用
什么是JWT JWT (JSON Web Token) 是一个开放标准 ( RFC 7519 ),它定义了一种紧凑且自包含的方式,用于在各方之间安全地以 JSON 对象的形式传输信息。由于这些信息经过数字签名,因此可以被验证和信任。JWT 可以使用密钥(采用HMAC算…...