Java 中的 OHC 缓存

OHC Caching in Java

我正在了解 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 将整个缓存拆分为 'segments',这样只有当两个条目散列到同一段时,一个操作才必须等待另一个。这类似于关系数据库中的 table 级锁定。

  • cpus的意思已经很清楚了
  • 默认 segmentCount2 的最小幂,大于 CPU 计数的两倍。有关将 CPU 计数加倍以优化吞吐量的逻辑,请参见 .
  • 示例
  • capacity 是缓存中可存储的总数据大小。默认值为每个内核 16MB。这可能是为了与 CPU cache sizes 相对应而设计的,尽管用户可能会了解其应用程序的实际容量需求,并且很可能会配置此值而不使用默认值。

实际的roundUpToPowerOf2可以这样解释: 不要超过 max,也不要低于 1。 (我想这取决于调用者来确保 max 是 2 的幂,或者在这种情况下它不是也可以。)在两者之间:为了获得 2 的幂,我们需要一个 int由单个一位(或全零)组成。 Integer#highestOneBit 给出了这样一个数字,其开启位是其参数中最左边的开启位。所以我们需要为它提供一个数字,其最左边的开启位是:

  • number相同,如果它已经是2的幂,或者
  • number最左边一位的左边一位。

左移前计算number - 1是第一种情况。如果 number 是 2 的幂,那么按原样左移会给我们 next 2 的幂,这不是我们想要的。对于第二种情况,number(或者它的值被 1 减去)左移打开下一个更大的位,然后 Integer#highestOneBit 有效地消隐了右边的所有位。