我正在学习 Java 堆外缓存并使用 OHC 缓存。我发现了 OHC 的源代码,它包含我不知道它们有什么用途的方法。希望有人能给我解释一下,谢谢。
int cpus = Runtime.getRuntime().availableProcessors(); // my CPU = 4
segmentCount = roundUpToPowerOf2(cpus * 2, 1 << 30);
capacity = Math.min(cpus * 16, 64) * 1024 * 1024;
static int roundUpToPowerOf2(int number, int max) {
return number >= max ? max : (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1;
}
最佳答案
为了最大限度地减少锁争用,OHC 将整个缓存拆分为“段”,这样只有当两个条目散列到同一段时,一个操作才必须等待另一个。这类似于关系数据库中的表级锁定。
cpus
的意思已经很清楚了。- 默认
segmentCount
是大于 CPU 计数两倍的2
的最小幂。有关将 CPU 数量加倍以优化吞吐量的逻辑,请参见示例 https://stackoverflow.com/a/4771384 . capacity
是缓存中可存储数据的总大小。默认值为每个内核 16MB。这可能是为了与 CPU cache sizes 对应而设计的,尽管用户大概知道他们的应用程序的实际容量需求,并且很可能会配置此值而不使用默认值。
实际的roundUpToPowerOf2
可以解释如下:
不要超过 max
,也不要低于 1
。 (我想这取决于调用者来确保 max 是 2 的幂,或者在这种情况下它不是也可以。)在两者之间:要获得 2 的幂,我们需要一个 int
由一位(或全零)组成。 Integer#highestOneBit
给出这样一个数字,其开启位是其参数中最左边的开启位。所以我们需要为它提供一个数字,其最左边的开启位是:
- 如果它已经是 2 的幂,则与
number
相同,或者 number
最左边一位的左边一个位置。
左移前计算number - 1
是第一种情况。如果 number
是 2 的幂,那么按原样左移会给我们 next 2 的幂,这不是我们想要的。对于第二种情况,number
(或者它的值减去 1
)左移打开下一个更大的位,然后 Integer#highestOneBit
有效将右侧的所有位都清空。
关于java - Java 中的 OHC 缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70738216/