簡體   English   中英

如何避免從Guava Cache中刪除條目

[英]How to avoid evicting entries from Guava Cache

我正在使用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);

我的猜測是你可能會添加重復的密鑰。

UPDATE

從JavaDocs for RemovalCause.REPLACED

條目本身實際上並未刪除,但其值已被用戶替換。 這可以由用戶調用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的源LocalCache ,零權重意味着不可驅逐的對象:

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

我不經常使用稱重器,但我相信當你使用0的重量時,這會導致你的價值被驅逐。

此外,請注意文檔說不要與maximumSize結合使用重量。

來自CacheBuilder.html#maximumWeight

當權重為零時,元素將在加載到緩存后立即被逐出。 這在測試中很有用,或者在沒有代碼更改的情況下暫時禁用緩存。

請注意,權重僅用於確定緩存是否超過容量; 它對選擇下一個應該被驅逐的條目沒有影響。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM