如何避免Java中的伪共享问题_@Contended注解与填充优化

夏芳小哥_6726

夏芳小哥_6726

2026-03-21

745人浏览

原创

伪共享问题出在CPU缓存行对齐失效环节:多个线程修改同一缓存行内不同变量,引发不必要的缓存同步,导致吞吐下降而不报错。

如何避免java中的伪共享问题_@contended注解与填充优化

Java伪共享到底在哪个环节出问题

伪共享本质是CPU缓存行(cache line)对齐失效导致的性能损耗:多个线程频繁修改位于同一缓存行内的不同变量,引发不必要的缓存同步(false invalidation)。它不报错、不崩溃,只悄悄拖慢并发吞吐——尤其在高争用、低延迟场景下,AtomicLong计数器或环形缓冲区(如Disruptor)里相邻字段常中招。

关键判断:如果你观察到线程数增加但吞吐不升反降,且热点方法里有多个独立的volatile字段或原子类型紧挨着定义,大概率是伪共享在作祟。

@Contended注解怎么用才生效

@Contended是JDK 8u20+引入的解决方案,但它默认关闭,且仅对特定JVM参数和类加载路径有效。不配参数,加了也白加。

  • 必须启用JVM参数:-XX:+UseContended(JDK 9+默认开启,但JDK 8必须显式加)
  • 若类不在java.*或sun.*包下,需额外指定-XX:ContendedPaddingWidth=64(推荐值,对应主流CPU缓存行长度)
  • 注解可加在类、字段或内部类上;加在字段上时,该字段会被单独隔离到新缓存行,前后自动填充
  • 注意:使用@Contended的类会被JVM特殊处理,可能导致类加载变慢,不适合高频动态生成的类

示例:

@Contended
public class Counter {
    public volatile long value;
}

此时value前后会插入约128字节填充(取决于ContendedPaddingWidth),确保它独占缓存行。

java-api-doc-generator
java-api-doc-generator

分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。

下载

手动填充字段比@Contended更可控吗

手动填充(如定义7个long字段把目标字段隔开)看似简单,但实际更难维护,且容易因JVM字段重排序或压缩Oops失效。

  • JVM可能对未使用的填充字段做优化(尤其是逃逸分析后),导致填充“塌缩”
  • 32位JVM或开启-XX:+UseCompressedOops时,对象头大小变化会影响字段偏移,手动计算的填充量可能不准
  • @Contended由JVM保证填充语义稳定,且支持运行时开关调试,比硬编码填充字段更可靠
  • 如果无法升级JDK或受限于容器环境(如某些Alpine镜像默认无JDK 8u20+),才考虑手动填充,并务必用Unsafe.objectFieldOffset()验证字段真实偏移

伪共享优化后为什么反而变慢了

常见反模式:在不该隔离的地方强行隔离,或者隔离粒度失控。

  • 过度使用@Contended会导致对象体积暴涨(一个@Contended字段可能让对象多占256+字节),加剧GC压力和内存带宽消耗
  • 缓存行隔离只对“高频率写、低频率读、彼此无依赖”的字段有效;若两个字段常被一起读(如x和y构成坐标),强行拆开反而破坏局部性,降低L1缓存命中率
  • 注意JVM版本差异:JDK 10+对@Contended做了填充策略优化,但早期版本填充更激进,实测前建议用jol(Java Object Layout)工具看真实内存布局

真正要盯住的,不是“有没有加@Contended”,而是“改完之后,L3缓存失效次数是否下降、每核IPC是否回升”——这些得靠perf stat -e cache-misses,cache-references这类底层指标验证。

伪共享不是靠加个注解就一劳永逸的事,它要求你既懂CPU缓存行为,又得信得过自己看到的内存布局和性能计数器。稍不注意,优化就变成负优化。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

11677

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

8782

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7552

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1244

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

1008

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1496

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

3069

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20311

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1335

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习