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

Java中的伪共享(False Sharing):隐藏的性能杀手与高并发优化实战

引言

在高性能Java应用中,开发者通常会关注锁竞争、GC频率等显性问题,但一个更隐蔽的陷阱——伪共享(False Sharing)​——却可能让精心设计的并发代码性能骤降50%以上。伪共享是由CPU缓存架构引发的底层问题,常见于多线程频繁修改“相邻”变量的场景。本文将深入剖析伪共享的底层原理,结合性能测试与实战代码,提供系统的优化方案。


一、什么是伪共享?
1. 从CPU缓存行说起

现代CPU通过缓存行(Cache Line)​​(通常64字节)批量加载内存数据。当两个线程分别修改同一缓存行中的不同变量时,即使变量逻辑无关,也会触发缓存行的反复失效与同步,导致性能急剧下降。这种现象称为伪共享。

2. 示例场景
class Data {volatile long x; // 线程1频繁修改volatile long y; // 线程2频繁修改
}

假设xy位于同一缓存行,线程1修改x会导致线程2的缓存行失效,反之亦然。尽管xy无竞争关系,但性能表现类似强制同步。


二、伪共享的性能影响
1. 测试对比:有无伪共享的吞吐量差异

使用JMH(Java Microbenchmark Harness)对以下两种结构进行测试:

// 伪共享场景
class SharedData {volatile long a;volatile long b;
}// 解决伪共享后的结构
class PaddedData {volatile long a;private long p1, p2, p3, p4, p5, p6, p7; // 填充56字节volatile long b;
}

结果​:

  • 伪共享结构:每秒操作数约500万次。
  • 填充后的结构:每秒操作数约4000万次,性能提升8倍
2. 火焰图与性能分析

通过Async-Profiler观察缓存未命中事件(L1-dcache-load-misses),可发现伪共享导致的高缓存失效率。


三、解决方案:从编码到JVM的优化手段
1. 手动填充(Padding)

通过添加无意义字段,确保变量独占缓存行:

class PaddedAtomicLong extends AtomicLong {public volatile long p1, p2, p3, p4, p5, p6, p7 = 0L; // 填充56字节
}

缺点​:代码冗余,且对象大小增加可能影响内存布局。

2. 使用@Contended注解(Java 8+)

JDK8引入的@sun.misc.Contended注解可自动填充字段,需开启JVM参数-XX:-RestrictContended

class Data {@Contendedvolatile long x;volatile long y;
}

优势​:简洁,且填充字节数可配置(-XX:ContendedPaddingWidth=64)。

3. 调整数据结构布局
  • 将高频修改的字段隔离到独立对象中。
  • 使用数组+线程ID分散写入位置(如Disruptor环形队列的设计)。

四、实战案例:优化高并发计数器的性能
1. 场景描述

实现一个多线程计数器,每个线程独立累加自己的计数器,最终汇总结果。

class Counter {private final AtomicLong[] counts = new AtomicLong[16]; public Counter() {for (int i = 0; i < counts.length; i++) {counts[i] = new AtomicLong();}}public void increment(int threadId) {counts[threadId % 16].incrementAndGet();}
}

问题​:AtomicLong数组元素可能位于相邻内存,导致伪共享。

2. 优化方案

使用@Contended或填充后的PaddedAtomicLong

class PaddedAtomicLong extends AtomicLong {private volatile long p1, p2, p3, p4, p5, p6, p7;
}class OptimizedCounter {private final PaddedAtomicLong[] counts = new PaddedAtomicLong[16];// 初始化与使用方式同上
}
3. 优化结果
  • QPS从12万提升至95万,延迟降低80%。
  • 通过perf工具观察到L1-dcache-load-misses下降90%。

五、工具链:如何检测伪共享?
  1. Linux perf​:

    perf stat -e L1-dcache-load-misses,L1-dcache-loads java MyApp

    L1-dcache-load-misses率可能暗示伪共享。

  2. Intel VTune​:

    • 分析“False Sharing”事件,定位冲突变量。
  3. Java Object Layout (JOL)​​:
    查看对象内存布局,确认字段是否相邻:

    System.out(ClassLayout.parseClass(Data.class).toPrintable());

六、总结与最佳实践
  1. 何时需要关注伪共享?​

    • 高并发场景下,线程频繁修改共享数据结构。
    • 性能监控显示高缓存未命中率,但无明显锁竞争。
  2. 优化原则​:

    • 空间换时间​:通过填充牺牲少量内存换取性能。
    • 隔离写入热点​:分散变量到不同缓存行。
  3. 框架级解决方案参考​:

    • Disruptor:通过填充和缓存行对齐设计实现无锁高性能队列。
    • Agrona:提供DirectBufferAtomicBuffer避免伪共享。

最后建议​:在性能关键路径上,结合JOL和JMH验证优化效果,避免过度优化。

相关文章:

Java中的伪共享(False Sharing):隐藏的性能杀手与高并发优化实战

引言 在高性能Java应用中&#xff0c;开发者通常会关注锁竞争、GC频率等显性问题&#xff0c;但一个更隐蔽的陷阱——伪共享&#xff08;False Sharing&#xff09;​——却可能让精心设计的并发代码性能骤降50%以上。伪共享是由CPU缓存架构引发的底层问题&#xff0c;常见于多…...

GO语言语法---switch语句

文章目录 基本语法1. 特点1.1 不需要break1.2 表达式可以是任何类型1.3 省略比较表达式1.4 多值匹配1.5 类型switch1.6 case穿透1.7 switch后直接声明变量1.7.1 基本语法1.7.2 带比较表达式1.7.3 不带比较表达式1.7.4 结合类型判断 1.8 switch后的表达式必须与case语句中的表达…...

开疆智能Profient转ModbusTCP网关连接ABB机器人MODBUS TCP通讯案例

本案例是通过开疆智能Profinet转ModbusTCP网关将西门子PLC与ABB机器人进行通讯 因西门子PLC采用Profinet协议&#xff0c;而ABB机器人采用的是ModbusTCP通讯。故采取此种方案。 配置过程&#xff1a; 1.MODBUS/TCP基于以太网&#xff0c;故ABB机器人在使用时需要有616-1PCIN…...

解决qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

可以参考&#xff1a;解决qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed-CSDN博客 讲的是程序执行目录下可能缺少了&#xff1a; libssl-1_1-x64.dll 和 libcrypto-1_1-x64.dll 库文件&#xff0c;将其复制到可执行文件exe的同级目录下即可…...

【洛谷P3386】二分图最大匹配之Kuhn算法/匈牙利算法:直观理解

题目&#xff1a;洛谷P3386 【模板】二分图最大匹配 &#x1f955; 匈牙利算法本来是针对带权图最大匹配的&#xff0c;这里由于题目只是求最大匹配的边数&#xff0c;所以我们也只考虑无权的情况。 &#x1f680; 本文旨在服务于看了别的关于匈牙利算法的文章但不甚理解的童…...

Text2SQL:自助式数据报表开发---0517

Text2SQL技术 早期阶段&#xff1a;依赖于人工编写的规则模板来匹配自然语言和SQL语句之间的对应关系 机器学习阶段&#xff1a;采用序列到序列模型等机器学习方法来学习自然语言与SQL之间的关系 LLM阶段&#xff1a;借助LLM强大的语言理解和代码生成能力&#xff0c;利用提示…...

使用Visual Studio将C#程序发布为.exe文件

说明 .exe 是可执行文件&#xff08;Executable File&#xff09;的扩展名。这类文件包含计算机可以直接运行的机器代码指令&#xff0c;通常由编程语言&#xff08;如 C、C、C#、Python 等&#xff09;编译或打包生成。可以用于执行自动化操作&#xff08;执行脚本或批处理操…...

写spark程序数据计算( 数据库的计算,求和,汇总之类的)连接mysql数据库,写入计算结果

1. 添加依赖 在项目的 pom.xml&#xff08;Maven&#xff09;中添加以下依赖&#xff1a; xml <!-- Spark SQL --> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_2.12</artifactId> <version>3.3.0…...

React Flow 边的基础知识与示例:从基本属性到代码实例详解

本文为《React Agent&#xff1a;从零开始构建 AI 智能体》专栏系列文章。 专栏地址&#xff1a;https://blog.csdn.net/suiyingy/category_12933485.html。项目地址&#xff1a;https://gitee.com/fgai/react-agent&#xff08;含完整代码示​例与实战源&#xff09;。完整介绍…...

oracle 资源管理器的使用

14.8.2资源管理器的使用 资源管理器控制CPU资源使用说明&#xff1a;  第一种分配方法&#xff1a;EMPHASIS CPU 分配方法确定在资源计划中对不同使用者组中的会话的重视程度。CPU占用率的分配级别为从1 到8&#xff0c;级别1 的优先级最高。百分比指定如何将CPU 资源分配给每…...

新手入门系列-linux系统下安装和使用docker

新手入门系列一 virtualbox+vagrant创建linux虚拟机 新手入门系列二 linux系统下安装和使用docker 前言 前面一章节我们安装了unbuntu虚拟机,这一节我们在虚拟机上安装和使用docker。 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的…...

mysql中4种扫描方式和聚簇索引非聚簇索引【爽文一篇】

目录 一 mysql的聚簇索引&非聚簇索引 1.1 数据表 1.2 聚簇索引 1.3 非聚簇索引 1.4 覆盖索引 二 mysql的4种扫描查询 2.1 全表扫描 2.2 索引扫描 2.3 覆盖索引扫描 2.4 回表扫描 2.5 总结 三 mysql的回表查询详解 3.1 回表查询 一 mysql的聚簇索引&非聚簇…...

贝叶斯优化Transformer融合支持向量机多变量回归预测,附相关性气泡图、散点密度图,Matlab实现

贝叶斯优化Transformer融合支持向量机多变量回归预测&#xff0c;附相关性气泡图、散点密度图&#xff0c;Matlab实现 目录 贝叶斯优化Transformer融合支持向量机多变量回归预测&#xff0c;附相关性气泡图、散点密度图&#xff0c;Matlab实现效果一览基本介绍程序设计参考资料…...

水平可见直线--上凸包(andrew算法

P3194 [HNOI2008] 水平可见直线 - 洛谷 不过只有90% #include<bits/stdc.h> using namespace std; #define N 100011 typedef long long ll; typedef pair<ll,int> pii; int n; struct no {double k,b;int id; }a[N],an[N]; int k; bool cmp(no a,no b) {if(a.k…...

【mysql】并发 Insert 的死锁问题 第二弹

上次死锁的场景还历历在目&#xff08;【mysql】并发 Insert 的死锁问题&#xff1a;Deadlock found when trying to get lock&#xff1b; try restarting transaction_1213 - deadlock found when trying to get lock; try-CSDN博客&#xff09;&#xff0c;这次又把代码写死…...

Docker配置SRS服务器 ,ffmpeg使用rtmp协议推流+vlc拉流

目录 演示视频 前期配置 Docker配置 ffmpeg配置 vlc配置 下载并运行 SRS 服务 推拉流流程实现 演示视频 2025-05-18 21-48-01 前期配置 Docker配置 运行 SRS 建议使用 Docker 配置 Docker 请移步&#xff1a; 一篇就够&#xff01;Windows上Docker Desktop安装 汉化完整指…...

一个stm32工程从底层上都需要由哪些文件构成

原文链接&#xff1a;https://kashima19960.github.io/2025/05/17/stm32/一个stm32工程从底层上都需要由哪些文件构成/ 前言 我最近因为做课设要用到stm32&#xff0c;所以去找了一些开源的stm32工程来看看&#xff0c;然后发现现在新版的keil mdk对于环境的配置跟以前 相比发…...

[Mac] 开发环境部署工具ServBay 1.12.2

[Mac] 开发环境部署工具ServBay 链接&#xff1a;https://pan.xunlei.com/s/VOQS0LDsC_J6XU4p-R6voF6YA1?pwdnbyg# 非常给力的本地 Web 开发/测试环境工具&#xff1a;ServBay。之前我们本地搭个 PHP MySQL Nginx 环境&#xff0c;或者搞个 PHP web 环境啥的&#xff0c;不…...

商城小程序源码介绍

今天要为大家介绍一款基于ThinkPHP、FastAdmin以及UniApp开发的商城小程序源码&#xff0c;这款源码在设计和功能上都有不俗的表现&#xff0c;非常适合想要搭建线上商城的开发者。 该源码采用了ThinkPHP作为后端框架&#xff0c;利用其强大的性能和灵活性&#xff0c;保障了系…...

鸿蒙OSUniApp 实现图片上传与压缩功能#三方框架 #Uniapp

UniApp 实现图片上传与压缩功能 前言 在移动应用开发中&#xff0c;图片上传是一个非常常见的需求。无论是用户头像、朋友圈图片还是商品图片&#xff0c;都需要上传到服务器。但移动设备拍摄的图片往往尺寸较大&#xff0c;直接上传会导致流量消耗过大、上传时间过长&#x…...

科技项目验收测试对软件产品和企业分别有哪些好处?

科技项目验收测试是指在项目的开发周期结束后&#xff0c;针对项目成果进行的一系列验证和确认活动。其目的是确保终交付的产品或系统符合预先设定的需求和标准。验收测试通常包括功能测试、性能测试、安全测试等多个方面&#xff0c;帮助企业评估软件在实际应用中的表现。 科…...

javascript和vue的不同

1. 数据绑定方式 JavaScript&#xff08;原生&#xff09; 手动操作 DOM&#xff1a;通过document.querySelector()等方法获取 DOM 元素&#xff0c;然后直接修改其属性或内容。 示例&#xff1a; <div id"counter">0</div> <button onclick"i…...

duxapp 2025-01-06更新 CLI新增帮助支持,优化基础模块结构

CLI 新增帮助命令 yarn duxapp -h yarn duxapp --helpyarn duxapp icon -h yarn duxapp icon create -h基础库 完善所有函数和组件的Types移除 Detail 组件移除 checkLocationPermission 方法移除 duxapp/utils/app.js 有关于模块的方法移除 Queue 队列功能移除 recursionSe…...

汽车零部件冲压车间MES一体机解决方案

在当前制造业升级的大背景下&#xff0c;提升生产效率、实现精细化管理已成为企业竞争力的关键。特别是在汽车零部件制造领域&#xff0c;冲压车间作为生产流程中的重要一环&#xff0c;其生产数据的实时采集与分析对于确保产品质量、优化生产节拍、降低运营成本至关重要。今天…...

hysAnalyser 从MPEG-TS导出ES功能说明

摘要 hysAnalyser 是一款特色的 MPEG-TS 数据分析工具。本文主要介绍了 hysAnalyser 从MPEG-TS 中导出选定的 ES 或 PES 功能(版本v1.0.003)&#xff0c;以便用户知悉和掌握这些功能&#xff0c;帮助分析和解决各种遇到ES或PES相关的实际问题。hysAnalyser 支持主流的MP1/MP2/…...

家里wifi不能上网或莫名跳转到赌博及色情网站就是域名被劫持、DNS被污染了

文章目录 定义上网过程域名被劫持可能阶段案例排查工具 解决方法清除系统DNS缓存查看DNS缓存清除DNS缓存 登录路由器&#xff0c;设置DNS可用的DNS地址&#xff1a; 找网络运营商报警 定义 DNS&#xff08;Domain Name System&#xff0c;域名系统&#xff09;劫持&#xff0c…...

基于SSM实现的健身房系统功能实现十六

一、前言介绍&#xff1a; 1.1 项目摘要 随着社会的快速发展和人们健康意识的不断提升&#xff0c;健身行业也在迅速扩展。越来越多的人加入到健身行列&#xff0c;健身房的数量也在不断增加。这种趋势使得健身房的管理变得越来越复杂&#xff0c;传统的手工或部分自动化的管…...

【Java微服务组件】分布式协调P1-数据共享中心简单设计与实现

欢迎来到啾啾的博客&#x1f431;。 记录学习点滴。分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 欢迎评论交流&#xff0c;感谢您的阅读&#x1f604;。 目录 引言设计一个共享数据中心选择数据模型键值对设计 数据可靠性设计持久化快照 &#xff08…...

[Harmony]大文件持久化

1.添加权限 在module.json5文件中添加权限 "requestPermissions": [{"name": "ohos.permission.READ_WRITE_USER_FILE", // 读写用户数据"reason": "$string:read_write_user_file_reason","usedScene": {"…...

pgsql14自动创建表分区

最近有pgsql的分区表功能需求&#xff0c;没想到都2025年了&#xff0c;pgsql和mysql还是没有自身支持自动创建分区表的功能 现在pgsql数据库层面还是只能用老三样的办法来处理这个问题&#xff0c;每个方法各有优劣 1. 触发器 这是最传统的方法&#xff0c;通过创建一个触发…...