伪共享False sharing说明JVM底层技术也不让人那么放心。
内存缓存系统中基本单元是高速缓存行(Cache lines). cpu会把数据从内存加载到高速缓存中 ,这样可以获得更好的性能,高速缓存默认大小是64 Byte为一个区域,一个区域在一个时间点只允许一个核心操作,也就是说不能有多个核心同时操作一个缓存区域。
因为高速缓存是64字节,而Hotspot JVM的对象头是两个部分组成,第一部分是由24字节的hash code和8字节的锁等状态标识组成,第二部分是指向该对象类的引用。基本类型字节如下:
doubles (8) and longs (8)
ints (4) and floats (4)
shorts (2) and chars (2)
booleans (1) and bytes (1)
references (4/8)
因此,一个高速缓存64字节可以放下多个字段,如果这多个字段位于同一个高速缓存区,虽然它们是类的不同字段,如下代码:
Class A{ int x; int y; } |
x和y被放在同一个高速缓存区,如果一个线程修改x;那么另外一个线程修改y,必须等待x修改完成后才能实施。
虽然两个线程修改各种独立变量,但是因为这些独立变量被放在同一个高速缓存区,性能就影响了。测试结果如后面。
当多核CPU线程同时修改在同一个高速缓存行各自独立的变量时,会不自不觉地影响性能,这就发生了伪共享False sharing,伪共享是性能的无声杀手。
解决方便是将高速缓存剩余的字节填充填满(pad),确保不发生多个字段被挤入一个高速缓存区,下面测试结果图就是和填充后性能比较。
实现字节填充的框架有 Disruptor,在RingBuffer中实现填充。关于Disruptor可见infoQ这个视频,用1毫秒的延时得到100K+ TPS吞吐量,JDK的ArrayQueue并行环境不见得是最快的,该视频后面讨论很多,让人大跌眼镜啊,开放源码多有好处啊,别人能发现你不能发现的漏洞。另外一篇解剖Disruptor
C#也有类似伪共享发生,见这里
转:http://www.jdon.com/42451
相关推荐
了解内存层次结构有助于理解CPU缓存对并发性能的影响,如缓存一致性协议和伪共享问题。 总结起来,这个学习资料集涵盖了以下关键知识点: 1. Java线程的生命周期和状态转换。 2. 线程同步机制:`synchronized`...
本文对 Java 并发编程中的重要知识点进行了总结,涵盖了 volatile 变量、原子操作、内存屏障、happens-before 保证、多线程环境下的伪共享和 Busy spin 等概念。 volatile 变量 Java 中可以创建 volatile 类型的...
- **伪共享问题**:多个处理器缓存同一数据块导致性能下降。 - **软中断**:由软件产生的中断信号。 - **分段分页问题与解决**:分段解决了程序逻辑地址与物理地址的映射,分页则解决了内存碎片问题。 - **并行与...
以上讨论了Java核心技术中的几个关键概念,包括`volatile`关键字的使用、同步代码的设计、伪共享问题以及busy spin机制的应用场景。理解这些知识点对于开发高效且可靠的多线程应用程序至关重要。在准备Java面试时,...
当JVM加载一个类时,如果该类包含`static`修饰的成员变量和方法,JVM会在固定内存位置为其分配空间,这使得它们在整个类的生命周期中都可以被快速访问。静态成员变量和方法不会随着对象的创建和销毁而改变,它们属于...
伪共享发生在多线程环境中,当多个线程频繁修改位于同一CPU高速缓存行上的不同变量时,可能导致整个缓存行被频繁地在不同的CPU之间传递,从而降低程序性能。可以通过将数据结构设计得更加合理来避免伪共享。 #### ...
9. **伪共享**:当多个线程修改共享内存中的不同数据,但由于这些数据在缓存行中相邻,导致的误同步现象。可以通过对变量进行对齐或者使用特定的同步原语来避免。 10. **可重入锁、乐观锁、悲观锁、公平锁、非公平...
- **HotSpot虚拟机的算法实现**:包括OopMap记录对象结构,安全点和安全区域保证垃圾收集时线程的同步,以及写屏障处理伪共享问题。 6. **并发可达性分析**:G1和CMS等收集器采用三色标记法,允许垃圾收集与应用...
5. **缓存行与伪共享(False Sharing)**:由于缓存行的存在,当多个线程同时访问同一缓存行中的不同变量时,可能会出现伪共享问题,即使这些变量在内存中是分开的。这种情况下,可以通过调整数据结构布局来避免。 ...
伪共享(False Sharing)是一个多线程性能问题,当不同的线程对共享缓存行内的不同变量进行修改时,即使这些变量在逻辑上是不相关的,也会导致性能下降,因为处理器可能需要额外的同步操作来保持一致性。 Busy Spin...
Clojure是一种基于Lisp的函数式编程语言,它运行在Java虚拟机(JVM)上。这个压缩包“Clojure的现代密码学(libsodiumNaCl).zip”显然是关于使用Clojure实现现代密码学方法的一个项目,特别是围绕着libsodium和NaCl库...
例如,在Java虚拟机(JVM)中,`main()`方法所在的线程通常被称为**主线程**。通过调用线程的`start()`方法启动线程,而当`run()`方法执行完毕后,该线程也就随之终止。 2. **线程的组成要素:** - 每个线程都由三个...
- **缓存分析**:考察缓存大小、Intel与AMD的L3缓存垂直差异、缓存未命中率和延迟,以及缓存行大小、对齐问题、缓存感知数据结构(如零填充)、在飞行数据压缩与解压缩、缓存行伪共享以及L3预取策略。 - **TLB...
本指南将详细解释如何在单节点上以伪分布式模式安装和配置Hadoop 0.20.2。 首先,安装Java环境。Hadoop需要Java 1.6.x或更高版本才能运行。在Ubuntu上,可以通过以下步骤安装Java: 1. 添加Canonical仓库: ``` ...
4. CSS选择器包括:标签选择器、类选择器、ID选择器、属性选择器、伪类和伪元素等。 5. 使用CSS3,可以通过`border-radius`实现矩形框圆角效果,如`border-radius: 10px;`;而50%红色透明效果可通过`background-...
6. **Spark部署模式**:Spark可以部署为单机模式、单机伪分布式、集群分布式(完全分布式),但没有列分布式这一说法。 7. **Spark Streaming输入数据流**:Kafka、Twitter和TCP套接字都是Spark Streaming常见的...
4. CSS选择器包括:标签选择器、类选择器、ID选择器、属性选择器、伪类和伪元素等。 5. CSS3实现圆角效果:`border-radius`属性;50%红色透明:`background: rgba(255, 0, 0, 0.5)`。 6. Div与Table的区别:Div更...
在Java编程语言中,`synchronized`关键字是用于实现线程同步和互斥的关键机制,它确保了在多线程环境下对共享资源的访问控制。面试中,`synchronized`通常是一个必问的话题,因为它在并发编程中的核心地位至关重要。...