缓存伪共享

共享对象存在同一个缓存中,由于MESI协议,一个对象中一些不需要改变的属性因为其他改变的属性,导致整个对象的缓存进入到M被修改状态。

目前的CPU是通常按照32或者64字节的缓存行(Cache Line)进行读取,如果读取的数据在同一个CacheLine,就存在缓存伪共享的问题。

对象被放入一个CacheLine中,根据MSEI协议,其中一个属性改变,其他所有没有改变的属性也变得不可共享。

填充Cache Line缓存块

通过填充对象,将对象中常被改变的属性和不常改变的属性分开到不通缓存Cache Line中。避免缓存的伪共享。

未填充对象:

public class DataPadding{

int value;

long modifyTime;

boolean flag;

long createTime;

char key;

}

对象结构:

# Running 64-bit HotSpot VM.

# Using compressed oop with 3-bit shift.

# Using compressed klass with 3-bit shift.

# Objects are 8 bytes aligned.

# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

com.hyr.jol.demo.JOLSample_02_Alignment$DataPadding object internals:

OFFSET SIZE TYPE DESCRIPTION VALUE

0 12 (object header) N/A

12 4 int DataPadding.value N/A

16 8 long DataPadding.modifyTime N/A

24 8 long DataPadding.createTime N/A

32 2 char DataPadding.key N/A

34 1 boolean DataPadding.flag N/A

35 1 (alignment/padding gap)

36 4 com.hyr.jol.demo.JOLSample_02_Alignment DataPadding.this$0 N/A

Instance size: 40 bytes

Space losses: 1 bytes internal + 0 bytes external = 1 bytes total

填充后对象:

public class DataPadding{

long a1,a2,a3,a4,a5,a6,a7,a8;//防止与前一个对象产生伪共享

int value;

long modifyTime;

long b1,b2,b3,b4,b5,b6,b7,b8;//防止不相关变量伪共享;

boolean flag;

long c1,c2,c3,c4,c5,c6,c7,c8;//

long createTime;

char key;

long d1,d2,d3,d4,d5,d6,d7,d8;//防止与下一个对象产生伪共享

}

对象结构:

# Running 64-bit HotSpot VM.

# Using compressed oop with 3-bit shift.

# Using compressed klass with 3-bit shift.

# Objects are 8 bytes aligned.

# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

com.hyr.jol.demo.JOLSample_02_Alignment$DataPadding object internals:

OFFSET SIZE TYPE DESCRIPTION VALUE

0 12 (object header) N/A

12 4 int DataPadding.value N/A

16 8 long DataPadding.a1 N/A

24 8 long DataPadding.a2 N/A

32 8 long DataPadding.a3 N/A

40 8 long DataPadding.a4 N/A

48 8 long DataPadding.a5 N/A

56 8 long DataPadding.a6 N/A

64 8 long DataPadding.a7 N/A

72 8 long DataPadding.a8 N/A

80 8 long DataPadding.modifyTime N/A

88 8 long DataPadding.b1 N/A

96 8 long DataPadding.b2 N/A

104 8 long DataPadding.b3 N/A

112 8 long DataPadding.b4 N/A

120 8 long DataPadding.b5 N/A

128 8 long DataPadding.b6 N/A

136 8 long DataPadding.b7 N/A

144 8 long DataPadding.b8 N/A

152 8 long DataPadding.c1 N/A

160 8 long DataPadding.c2 N/A

168 8 long DataPadding.c3 N/A

176 8 long DataPadding.c4 N/A

184 8 long DataPadding.c5 N/A

192 8 long DataPadding.c6 N/A

200 8 long DataPadding.c7 N/A

208 8 long DataPadding.c8 N/A

216 8 long DataPadding.createTime N/A

224 8 long DataPadding.d1 N/A

232 8 long DataPadding.d2 N/A

240 8 long DataPadding.d3 N/A

248 8 long DataPadding.d4 N/A

256 8 long DataPadding.d5 N/A

264 8 long DataPadding.d6 N/A

272 8 long DataPadding.d7 N/A

280 8 long DataPadding.d8 N/A

288 2 char DataPadding.key N/A

290 1 boolean DataPadding.flag N/A

291 1 (alignment/padding gap)

292 4 com.hyr.jol.demo.JOLSample_02_Alignment DataPadding.this$0 N/A

Instance size: 296 bytes

Space losses: 1 bytes internal + 0 bytes external = 1 bytes total

JDK1.8解决缓存伪共享

JDK1.8中增加了Contended注解方式来解决缓存伪共享问题。

在JDK1.8中,新增了一种注解@sun.misc.Contended,来使各个变量在Cache line中分隔开。注意,jvm需要添加参数-XX:-RestrictContended才能开启此功能

未填充对象:

public class DataPadding{

int value;

long modifyTime;

boolean flag;

long createTime;

char key;

}

对象结构:

# Running 64-bit HotSpot VM.

# Using compressed oop with 0-bit shift.

# Using compressed klass with 0-bit shift.

# Objects are 8 bytes aligned.

# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

com.hyr.jol.demo.JOLSample_02_Alignment$DataPadding object internals:

OFFSET SIZE TYPE DESCRIPTION VALUE

0 12 (object header) N/A

12 4 int DataPadding.value N/A

16 8 long DataPadding.modifyTime N/A

24 8 long DataPadding.createTime N/A

32 2 char DataPadding.key N/A

34 1 boolean DataPadding.flag N/A

35 1 (alignment/padding gap)

36 4 com.hyr.jol.demo.JOLSample_02_Alignment DataPadding.this$0 N/A

Instance size: 40 bytes

Space losses: 1 bytes internal + 0 bytes external = 1 bytes total

使用Contended注解:

public class DataPadding {

@sun.misc.Contended("group1")

int value;

@sun.misc.Contended("group1")

long modifyTime;

@sun.misc.Contended("group2")

boolean flag;

@sun.misc.Contended("group3")

long createTime;

@sun.misc.Contended("group3")

char key;

}

对象结构:

# Running 64-bit HotSpot VM.

# Using compressed oop with 0-bit shift.

# Using compressed klass with 3-bit shift.

# Objects are 8 bytes aligned.

# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

com.hyr.jol.demo.JOLSample_02_Alignment$DataPadding object internals:

OFFSET SIZE TYPE DESCRIPTION VALUE

0 12 (object header) N/A

12 4 com.hyr.jol.demo.JOLSample_02_Alignment DataPadding.this$0 N/A

16 128 (alignment/padding gap)

144 4 int DataPadding.value N/A

148 4 (alignment/padding gap)

152 8 long DataPadding.modifyTime N/A

160 128 (alignment/padding gap)

288 1 boolean DataPadding.flag N/A

289 135 (alignment/padding gap)

424 8 long DataPadding.createTime N/A

432 2 char DataPadding.key N/A

434 6 (loss due to the next object alignment)

Instance size: 440 bytes

Space losses: 395 bytes internal + 6 bytes external = 401 bytes total

如果想深入了解,可以看下关于CPU Cache、Linux Cache相关的知识。

java 缓存行填充_缓存伪共享问题以及解决方案缓存行填充相关推荐

  1. java中什么是 伪共享_【Java】聊聊多线程中的伪共享现象

    首页 专栏 java 文章详情 0 聊聊多线程中的伪共享现象 小强大人发布于 1 月 27 日 什么是伪共享? 讲伪共享之前,让我们先乘坐时光机,回到大学课堂,来重温下计算机组成原理的基础知识.我们知 ...

  2. 清空缓存的命令_超详细的mysql数据库查询缓存原理解析、涉及命令、流程分析等...

    概述 mysql查询缓存在数据库优化可以起到很大的作用,今天主要针对这一块做一个总结,下面一起来看看吧~ 一.缓存条件,原理 MySQL Query Cache是用来缓存我们所执行的SELECT语句以 ...

  3. 左侧固定右侧自动填充_办公小技巧:解决Excel公式自动填充问题

    在Excel表格中,利用公式可以大大提高计算效率,而通过自动填充的方式将公式应用于更多的单元格,则可以再让效率猛增.但在具体使用公式填充的过程中,也可能会遇到一些问题. 1. 向下填充公式时填充柄找不 ...

  4. java缓存管理器_使用@EnableCaching的Spring Boot默认缓存管理器

    我在SpringBootApplication中实现了缓存,如下所示 @SpringBootApplication @EnableCaching public class SampleApplicat ...

  5. java excel 列数_计算Excel工作表列中的行数(提供的Java代码)

    在参考我之前的问题How to calculate number of rows in a column of Excel document using Java时,我能够计算给定表格中的总列数.现在 ...

  6. java调用网络打印机不稳定_新手处理共享打印机总是没有反应的故障

    共享打印机使用频率比较多,之前也写了不少维修的文章,但还是经常碰到很多人在这个问题上无法处理,希望本文能帮到你. 方法/步骤 一.共享打印机唤醒现在很多打印机都有自动睡眠功能,尤其在深度睡眠状态时候, ...

  7. java excel行高_使用apache poi在excel中使用行高调整图像高度

    也许这是一个愚蠢的问题,但我找不到解决方案 如何根据图像高度设置行高? 这是我的代码的一部分: int pictureIdx = workBook.addPicture(bytes, Workbook ...

  8. mysql数据库取奇数行数据_查询数据库中的奇数行和偶数行

    功能奇数次执行和偶数次执行时的结果不同的故障复盘 场景:将数据库查询到的数据,写入一个xls文件.完成后,多点几次,发现一个问题,偶数次生成的文件比较小,打开一看,里面只有一行,只有标题,没有内容.分 ...

  9. 多少行数_经验丰富的程序员和其每日代码行数

    John D. Cook是一位数学教授.程序员.顾问.经理人和统计学家,善于并享受结合运用这些技能来解决问题.他曾撰文说(中文): "最近,我听说了一个关于缺乏经验的程序员和经验丰富的程序员 ...

最新文章

  1. 很近没读书了,读书笔记之大道至简
  2. CURL NDK 交叉编译
  3. 关于collect2: cannot find ld的解决办法
  4. 后端技术:mybatis插件原理详解
  5. spring获取webapplicationcontext,applicationcontext几
  6. mangle 打标签冲突
  7. eplices如何导入外部代码_#华为云·寻找黑马程序员#【代码重构之路】如何优雅的关闭外部资源...
  8. C++析构函数为什么要为虚函数?
  9. 鸿鹄系统和鸿蒙系统区别,鸿蒙系统现身,搭配升降式镜头和鸿鹄芯片,你以为是手机?...
  10. maven项目配置私服
  11. 联想Thinkpad E430搜不到无线网络
  12. C# 键盘中的按键对应的KeyValue
  13. 双击启动PS软件界面不显示、PS无法打开,解决方法
  14. 用计算机给手机充电,用电脑USB口长期给手机充电有危险吗?
  15. dwa_planner解读
  16. js鼠标移动到某个元素上改变鼠标样式,如悬浮小手、禁用鼠标、等待...
  17. An Invitation to Algebraic Geometry
  18. android随笔25——搜索框输入内容后界面的隐藏逻辑
  19. 2020多媒体信号处理复习笔记
  20. 制作404页面的注意事项

热门文章

  1. 周六直播丨细致入微 – OceanBase云平台安装部署实战
  2. 系列 | 高性能存储-MySQL数据库之存储过程揭秘
  3. Oracle分区技术特性详细解读
  4. 华为云媒体査勇:华为云在视频AI转码领域的技术实践
  5. 解析云原生2.0架构设计的8大关键趋势
  6. Vue组件间的传值五大场景,你造吗?
  7. 鸿蒙轻内核源码分析:掌握信号量使用差异
  8. 从前世今生聊一聊,大厂为啥亲睐时序数据库
  9. Linux神器strace的使用方法及实践
  10. 区块链学习笔记:DAY01 区块链的技术原理