伪共享指的是多线程在对不一样变量进行修改操做时,若是变量位于同一个缓存行,当多线程竞争缓存行全部权时,每一个核都同时对缓存行进行修改,缓存子系统将会使其余核的缓存行失效致使cache miss,最后升级到L3缓存进行修改,最后大大影响程序的执行效率,若是竞争的核不在同一个cpu插槽即不共享L3缓存,那就会去内存中进行修改,这样引发的问题就是伪共享问题。数组
参考资料:缓存
图1性能
图1说明了伪共享的问题。在核心1上运行的线程想更新变量X,同时核心2上的线程想要更新变量Y。不幸的是,这两个变量在同一个缓存行中。每一个线程都要去竞争缓存行的全部权来更新变量。若是核心1得到了全部权,缓存子系统将会使核心2中对应的缓存行失效。当核心2得到了全部权而后执行更新操做,核心1就要使本身对应的缓存行失效。这会来来回回的通过L3缓存,大大影响了性能。若是互相竞争的核心位于不一样的插槽,就要额外横跨插槽链接,问题可能更加严重。线程
对于HotSpot JVM,全部对象都有两个字长的对象头。第一个字是由24位哈希码和8位标志位(如锁的状态或做为锁对象)组成的Mark Word。第二个字是对象所属类的引用。若是是数组对象还须要一个额外的字来存储数组的长度。每一个对象的起始地址都对齐于8字节以提升性能。所以当封装对象的时候为了高效率,对象字段声明的顺序会被重排序成下列基于字节大小的顺序:对象
- doubles (8) 和 longs (8)
- ints (4) 和 floats (4)
- shorts (2) 和 chars (2)
- booleans (1) 和 bytes (1)
- references (4/8)
- <子类字段重复上述顺序>