开发者

Laziness of eviction in Guava's maps

Current eviction algorithm for maps is quite lazy. It looks like expired objects are evicted only when the data structure is accessed.

For example, the map from addresses to indexers defined as:

ConcurrentMap<Address, Indexer> indexers = new MapMaker()
  .expireAfterAccess( EXPIRATION, TimeUnit.SECONDS)
  .evictionListener( new IndexEvicted())
  .makeMap();

leads to quite surprising pattern: while containsKey() for the given address returns false, immediately after that indexer for that address is evicted.

What would be the recommended approach to make the clean up process more real-time? I.e. to remove the objects close to the actual expiration time.

Update: I'd like to mor开发者_如何学运维e clarify what I mean by real-time. For the example above, EXPIRATION being 10 seconds, I'd like to see the inserted object evicted in 10 seconds after last access. That is not happening now - the map must be used somehow to start the eviction. If the map is completely unused, the object can stay there for years.


In order to have timely eviction, Guava would need to implement some sort of background thread or a timed recurring task. Doing so would make the map more heavy weight and harder to use in environments like J2EE or environments where the security policy prevents threads from being spawned willy-nilly.

If you care about timely eviction, set up your own timed thread that touches the map.

On the flip side, I do agree that having a garbage-collector triggered eviction would be nice... for example by using a SoftReference and a finalizer. (Yes, I know finalizers are mostly evil, I am simply suggesting an optional last-resort strategy.)


There is an expireAfterWrite method in addition to expireAfterAccess. That probably fits the bill.

From javadoc:

Specifies that each entry should be automatically removed from the map once a fixed duration has passed since the entry's creation or replacement. Note that changing the value of an entry will reset its expiration time.

Note: both expireAfterAccess and expireAfterWrite are "real-time", it's just that one expires elements based on their last write time, the other is based on their last access time.


While Dilum's answer makes the most sense, also note that touching a data structure with automatic eviction will not necessarily evict all expired entries. Most expiry happens in relatively small batches and therefore, if you have a large number of simultaneous expirations, you might have to touch the data structure a number of times. Unfortunately, I don't think there there is an easy programmatic way to do this reliably.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜