2013-12-17 30 views
4

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

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); 

回答

6

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

UPDATE

从JavaDoc中RemovalCause.REPLACED

的条目本身实际上并没有删除,但它的价值被用户所取代。 (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源,零权重是指非evictable对象:

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

谢谢Andrey,刚刚改变重量为1,仍然看到相同的行为。 – user379151

+0

嘿,我的回答说,问题是不是用秤,它可能是 –

+0

好的,回去验证,被替换的是唯一的密钥,没有找到重复。 – user379151

0

我不秤经常使用,但我相信,当你使用一个重量为0,可能会导致被驱逐你的价值观。

此外,请注意,文档说不使用weight与maxSize结合使用。

从​​

当重量为零时,元件将被立即被 加载到高速缓冲存储器之后被逐出。这可以用于测试,或者在不更改代码的情况下暂时禁用 缓存。

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

此功能不能与maximumSize结合使用。

+0

感谢您的快速响应。改变称重器返回1,并删除maxSize,但没有变化:( – user379151