如何避免从Guava Cache中删除条目

时间:2013-12-17 22:04:28

标签: java caching guava

我正在使用Guava Cache在内存中缓存大约100K条记录。我使用cache.putAll(Map<K,V>)预加载缓存。加载大约20K记录后,我看到删除通知,原因是'REPLACED'。所有条目的最大大小为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);

2 个答案:

答案 0 :(得分:6)

我的猜测是你可能会添加重复的密钥。

<强>更新

来自RemovalCause.REPLACED的JavaDocs:

  

条目本身并未实际删除,但其值已被用户替换。这可以由用户调用Cache.put(K,V),LoadingCache.refresh(K),Map.put(K,V),Map.putAll(java.util.Map),ConcurrentMap.replace(Object,Object)引起),或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();
}

答案 1 :(得分:0)

我不经常使用称重器,但我相信当你使用0的重量时,这会导致你的价值被驱逐。

另外,请注意文档说不要使用权重与maximumSize结合使用。

来自CacheBuilder.html#maximumWeight

  

当权重为零时,元素将在被删除后立即被驱逐   加载到缓存中。这在测试或禁用时非常有用   临时缓存而无需更改代码。

     

请注意,权重仅用于确定缓存是否结束   容量;它对选择哪个条目应该被驱逐没有影响   下一个。

     

此功能不能与maximumSize一起使用。