4
votes

I'm using Guava Cache to cache about 100K records in memory. I use cache.putAll(Map<K,V>) to pre-load the cache. After loading about 20K records, I see removal notifications with cause 'REPLACED'. Max size is 1GB and weigher returns 1 for all entries, expireAfterAccess is 24 hours. 1GB is enough for all records. How can I ensure that no entry is replaced before 24 hrs ?

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

2 Answers

6
votes

My guess is that you might be adding duplicate keys.

UPDATE

From JavaDocs for RemovalCause.REPLACED:

The entry itself was not actually removed, but its value was replaced by the user. This can result from the user invoking Cache.put(K, V), LoadingCache.refresh(K), Map.put(K, V), Map.putAll(java.util.Map), ConcurrentMap.replace(Object, Object), or ConcurrentMap.replace(Object, Object, Object).

So since it's not a LoadingCache, judging by a doc, this leaves only two possibilities: a duplicate or a bug.


From the source of LocalCache, zero weight means non-evictable objects:

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

I do not use weigher very often, but I believe when you use a weight of 0, that can cause your values to be evicted.

Also, note that the documentation says not to use weight in conjuction with maximumSize.

From CacheBuilder.html#maximumWeight

When weight is zero, elements will be evicted immediately after being loaded into cache. This can be useful in testing, or to disable caching temporarily without a code change.

Note that weight is only used to determine whether the cache is over capacity; it has no effect on selecting which entry should be evicted next.

This feature cannot be used in conjunction with maximumSize.