我使用番石榴Cache在内存中缓存大约100 K的记录。我使用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);发布于 2013-12-17 22:26:16
我猜你可能是在添加重复的键。
更新
从JavaDocs到RemovalCause.REPLACED
条目本身并没有被实际删除,但是它的值被用户替换了。这可能是用户调用Cache.put(K,V)、LoadingCache.refresh(K)、Map.put(K、V)、Map.putAll(java.util.Map)、ConcurrentMap.replace(对象、对象)或ConcurrentMap.replace(对象、对象、对象)的结果。
因此,由于它不是一个LoadingCache,从文档判断,这只剩下两种可能性:复制或bug。
从LocalCache的来源来看,零权重意味着不可驱逐的对象:
ReferenceEntry<K, V> getNextEvictable() {
  for (ReferenceEntry<K, V> e : accessQueue) {
    int weight = e.getValueReference().getWeight();
    if (weight > 0) {
      return e;
    }
  }
  throw new AssertionError();
}发布于 2013-12-17 22:16:57
我不经常使用称重器,但我相信当你使用0的权重时,会导致你的值被逐出。
另外,请注意文档中说不要在与maximumSize的连接中使用权重。
来自CacheBuilder.html#maximumWeight
当权重为零时,元素将在加载到缓存后立即被逐出。这在测试中很有用,或者在没有代码更改的情况下暂时禁用缓存。 请注意,权重仅用于确定缓存是否超出容量;它对选择下一步应取消哪个条目没有任何影响。 此功能不能与maximumSize一起使用。
https://stackoverflow.com/questions/20645671
复制相似问题