对齐填充Padding(不够64字节用0填充)是用来解决伪共享问题,保证一个缓存行只读取一个数据,避免多个线程竞争同一个缓存行带来性能问题。

伪共享

CPU缓存是由多个缓存行组成的,缓存行是CPU和内存之间交互的最小单元,每个缓存行大小是64个字节,每次CPU读取数据以块为单位64个字节,一次读取一块数据(猜想上下位的数据也是需要的),避免多次交互,一个缓存行可以缓存多个数据(比如:X, Y, Z三个数据),当多个线程情况下,如果线程A修改数据X,线程B需要修改数据Y,但是都处于同一个缓存行,这时候会存在缓存行竞争,如果线程A获取到缓存行,那么线程B缓存行失效,修改数据会失败,如果线程B竞争到缓存行,线程A修改数据会失败,这样会多次请求失败,影响性能,这就是伪共享问题。

对齐填充代码演示

将下面类中数据对象由ValueNoPadding改成ValuePadding,我们会发现执行效率会高很过

public class ShareExample implements Runnable{public final static long ITERATIONS = 500L * 1000L * 100L;private int arrayIndex = 0;private static ValueNoPadding[] longs; //没有填充的对象数组public ShareExample(final int arrayIndex) {this.arrayIndex = arrayIndex;}public static void main(final String[] args) throws Exception {for(int i = 1; i < 10; i++){System.gc();final long start = System.currentTimeMillis();runTest(i);System.out.println(i + " Threads, duration = " + (System.currentTimeMillis() - start));}}private static void runTest(int NUM_THREADS) throws InterruptedException {Thread[] threads = new Thread[NUM_THREADS];longs = new ValueNoPadding[NUM_THREADS];for (int i = 0; i < longs.length; i++) {longs[i] = new ValueNoPadding();}for (int i = 0; i < threads.length; i++) {threads[i] = new Thread(new ShareExample(i));}for (Thread t : threads) {t.start();}for (Thread t : threads) {t.join();}}@Overridepublic void run() {long i = ITERATIONS + 1;while (0 != --i) {longs[arrayIndex].value = 0L;}}public final static class ValuePadding {protected long p1, p2, p3, p4, p5, p6, p7;protected volatile long value = 0L;  //64字节//64个字节protected long p9, p10, p11, p12, p13, p14;protected long p15;}//@Contended //java8public final static class ValueNoPadding {// protected long p1, p2, p3, p4, p5, p6, p7;protected volatile long value = 0L;  //8个字节.  MESI协议,保证缓存一致性.// protected long p9, p10, p11, p12, p13, p14, p15;}
}

Java8 @Contended

除了对字段进行填充之外,还有一个比较清爽的方法,那就是对需要避免陷入伪共享的字段进行注解。Java8中JEP142引入了@Contended注解,被这个注解修饰的字段必须和其他字段放在不同的位置,避免出现伪共享,其实原理也是实现了对齐填充,不过前提是需要通过JVM参数-XX:-RestrictContended开启此功能。

Idea中配置开启@Contented:

1) idea工具栏中 Help --> Edit Custom Vm Options
2) -XX参数中 boolean类型, -XX:+RestrictContended为该属性设置为true,-XX:-RestrictContended为属性设置为false;
3) 上述参数为JVM虚拟机启动时使用;

package com.lucifer.thread.padding;import sun.misc.Contended;public final class FalseSharing implements Runnable {public static int NUM_THREADS = 4; // changepublic final static long ITERATIONS = 500L * 1000L * 1000L;private final int arrayIndex;private static VolatileLong[] longs;public FalseSharing(final int arrayIndex) {this.arrayIndex = arrayIndex;}public static void main(final String[] args) throws Exception {Thread.sleep(10000);System.out.println("starting....");if (args.length == 1) {NUM_THREADS = Integer.parseInt(args[0]);}longs = new VolatileLong[NUM_THREADS];for (int i = 0; i < longs.length; i++) {longs[i] = new VolatileLong();}final long start = System.nanoTime();runTest();System.out.println("duration = " + (System.nanoTime() - start));}private static void runTest() throws InterruptedException {Thread[] threads = new Thread[NUM_THREADS];for (int i = 0; i < threads.length; i++) {threads[i] = new Thread(new FalseSharing(i));}for (Thread t : threads) {t.start();}for (Thread t : threads) {t.join();}}public void run() {long i = ITERATIONS + 1;while (0 != --i) {longs[arrayIndex].value = i;}}public static class VolatileLong {@Contendedpublic volatile long value = 0L;}
}

对齐填充@Contended相关推荐

  1. c语言格式对齐填充_C ++中类的大小 课堂上的填充和对齐| 派生类的大小

    c语言格式对齐填充 Prerequisite: 先决条件: sizeof() operator in C/C++ C / C ++中的sizeof()运算符 Size of struct in C C ...

  2. JVM中的对象探秘(三)- 对象的实例数据与对齐填充

    引言 上一篇文章我们讲解了JVM对象内存布局的第一部分对象头,今天我们继续来讲讲剩下的两部分实例数据(Instance Data) .对齐填充(Padding). 实例数据与对齐填充 这两部分我们放在 ...

  3. python怎么换行输出的数字对齐_python中格式化输出和字母大小写转换,对齐填充方式...

    #格式化输出 print("ang is a good time") str7="ong is a boy" num=10 f=5.22313 # %d(整数站 ...

  4. python输出右对齐填充_Python中符号如何对齐和填充

    python中关于符号的使用,有时需要考虑精度的要求,但是python默认的有可能不是很直观能看出它的有效宽度和精度,这个时候使用对齐和填充的方式可以帮助更好地理解程序,下面就是介绍的步骤: 工具/原 ...

  5. Java8的伪共享和缓存行填充--@Contended注释

    在我的前一篇文章<伪共享和缓存行填充,从Java 6, Java 7 到Java 8>中, 我们演示了在Java 8中,可以采用@Contended在类级别上的注释,来进行缓存行填充.这样 ...

  6. 2万字 + 50 张图,细说 JVM 内存分布、内存对齐、压缩指针

    今天为大家带来一篇 2 万字的硬核技术文章. 本文我们将从计算机组成原理的角度详细阐述对象在JVM内存中是如何布局的,以及什么是内存对齐,如果我们头比较铁,就是不进行内存对齐会造成什么样的后果,最后引 ...

  7. 7. 重磅硬核 | 一文聊透对象在JVM中的内存布局,以及内存对齐和压缩指针的原理及应用

    重磅硬核 | 一文聊透对象在JVM中的内存布局,以及内存对齐和压缩指针的原理及应用 大家好,我是bin,又到了每周我们见面的时刻了,我的公众号在1月10号那天发布了第一篇文章?<从内核角度看IO ...

  8. 一文聊透对象在JVM中的内存布局,以及内存对齐和压缩指针的原理及应用

    大家好,我是bin,又到了每周我们见面的时刻了,我在1月10号那天发布了第一篇文章<从内核角度看IO模型的演变>,在这篇文章中我们通过图解的方式以一个C10k的问题为主线,从内核角度详细阐 ...

  9. 了解C++类的大小和类变量的字节对齐

    空类: 空类没有内容,但是需要分配地址:大小为1个字节: 基础类: 下图类占用8个字节:i 是四字节:c本身是一字节大:为对齐填充了3个字节:总大小是8字节: double为8字节大:下图,4 + 4 ...

最新文章

  1. 清华微电子副所长尹首一:中国AI芯片的技术路线最全面
  2. 台湾高校首创气体灭火数位实境教育馆
  3. MS SQL Server 常用操作
  4. sql server 记录删除数据ip_玻璃做介质,用光记录或删除数据,全息云存储来了!...
  5. PHP5.3以上版本没有libmysql.dll,以及由此带来的困扰
  6. Shell中$X的含义
  7. webstorm 主题 配色
  8. struts2拦截器的一个使用实例
  9. Redis文档--详解redis
  10. 微信支付开发(1)--普通商户申请、账户验证、签约、公众号授权流程详解
  11. Java Web基础知识之文件上传:文件上传一窥究竟
  12. Ceres Solver (ubuntu 安装)
  13. 伽卡他卡学生端找不到计算机,伽卡他卡电子教室
  14. 价值4500的国际版多语言点赞抖音分享点赞任务平台源码(十二种语言)
  15. TypeScript下载安装
  16. 文件夹删不掉?有种文件夹叫 畸形文件夹
  17. Mantis 安装与配置
  18. 论文框架和目录一样吗_论文培训(音频+讲义)
  19. 【转】写给欲采访刘丁宁事件的媒体
  20. “泰迪杯”挑战赛 - 基于非侵入式负荷检测与分解针对日常电器的电力数据挖掘

热门文章

  1. 微信摇一摇插件ios_解决ios无法触发摇一摇兼容,Cordova实现模仿微信摇一摇
  2. MrDoc——语雀的开源替代品,可私有部署、无用户限制、数据完全掌控
  3. web---relative
  4. 在linux中运行c语言程序,linux环境中运行C语言程序
  5. 过去的2011,再见,希望的2012,你好!
  6. 隐私计算中可信执行环境的一知半解
  7. linux基本功系列之uniq命令实战
  8. 齐博x2新功能:如何对CMS等频道内容进行数据分表进行文本储值
  9. Win10配置CUDA10+cuDNN7(pytorch,tensorflow-gpu)记录
  10. AI对室内设计师带来哪些新的机会以及影响