Caffeine源码中PadDrainStatus类大量byte填充字段的作用是什么
该设计的核心作用是避免CPU缓存伪共享,提升高并发场景下的执行性能
1. 背景:CPU伪共享的性能问题
- CPU的缓存是以*缓存行(Cache Line)*为最小单位存取数据的,目前主流服务器CPU的缓存行大小多为64字节,部分高端架构可达128字节。
- 如果两个逻辑独立、被不同CPU核心频繁读写的变量刚好存储在同一个缓存行中,任意一个变量被修改时,都会触发整个缓存行的失效同步,其他需要访问该缓存行的CPU核心必须重新从主内存拉取数据,哪怕它们访问的是完全无关的另一个变量,这种无效的同步开销就是伪共享,高并发场景下会严重拖慢性能。
2. 填充字段的设计逻辑
你看到的PadDrainStatus类中p000到p119的连续byte字段,是专门的缓存行填充占位符:
- 120字节的占位空间,足以覆盖市面上绝大多数CPU的缓存行大小,它的子类
DrainStatusRef中定义的高频读写的DRAIN_STATUS状态变量,会被这些占位字节完全隔离开,保证该状态变量独占一整个缓存行,不会和其他相邻变量共享缓存行。 - 采用父类继承的方式实现填充,是利用了JVM的对象内存布局规则:父类的字段会排列在子类字段的内存地址之前,不需要手动调整内存布局就能实现前置填充,从根源上消除伪共享带来的性能损耗。
内容的提问来源于stack exchange,提问作者ke xu
相关产品推荐
相关产品推荐

