我正在使用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);
答案 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一起使用。