java - 如何避免从 Guava 缓存中逐出条目

标签 java caching guava

我正在使用 Guava Cache在内存中缓存大约 100K 条记录。我用 cache.putAll(Map<K,V>)预加载缓存。加载大约 20K 条记录后,我看到原因为“已替换”的删除通知。最大大小为 1GB,称重器对所有条目返回 1,expireAfterAccess 为 24 小时。 1GB 足以存储所有记录。如何确保在 24 小时之前没有条目被替换?

MyCacheLoader cacheLoader = new MyCacheLoader();
CacheBuilder<Long, Map<String, List<String>>> cacheBuilder = CacheBuilder.newBuilder().
        initialCapacity(1024 * 1024 * 1024).
        //maximumSize(1024 * 1024 * 1024).
        maximumWeight(1000000).
        weigher(new Weigher<Long, Map<String, List<String>>>(){
            public int weigh(Long arg0, Map<String, List<String>> arg1) {
                return 1;
            }
        }).
        concurrencyLevel(1).
        expireAfterAccess(24, TimeUnit.HOURS);

cache = cacheBuilder.build(cacheLoader);

最佳答案

我的猜测是您可能添加了重复键。

更新

来自 RemovalCause.REPLACED 的 JavaDocs :

The entry itself was not actually removed, but its value was replaced by the user. This can result from the user invoking Cache.put(K, V), LoadingCache.refresh(K), Map.put(K, V), Map.putAll(java.util.Map), ConcurrentMap.replace(Object, Object), or ConcurrentMap.replace(Object, Object, Object).

因此,由于它不是 LoadingCache,根据文档判断,这只剩下两种可能性:重复或错误。


LocalCache的源码来看,零权重意味着不可驱逐的对象:

ReferenceEntry<K, V> getNextEvictable() {
  for (ReferenceEntry<K, V> e : accessQueue) {
    int weight = e.getValueReference().getWeight();
    if (weight > 0) {
      return e;
    }
  }
  throw new AssertionError();
}

关于java - 如何避免从 Guava 缓存中逐出条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20645671/

相关文章:

c# - 为什么 MemoryCache 抛出 NullReferenceException

java - 使用 Guava 的 ImmutableSortedMap 作为频率图

java - Play Location Services getLastLocation 返回 null

java - System.currentTimeMillis 与 System.nanoTime

html - 单击刷新按钮时,离线模式下 HTML 应用程序缓存出现问题

带有 Redis 缓存的 Django 1.9

java - 创建一个 ImmutableMap<P,ImmutableMultimap<C,V>> 流收集器

java - "Flatten"在 guava 和 java 7 中可选

Java 泛型 : wildcard extends class and include that class

java - 拆分字符串但仍显示所有元素