Ok, this is a cute bug.

Under the hood, UtilCache makes use of java.util.LinkedHashMap when
maxMemSize is set.  It configures LinkedHashMap to act like a LRU map;
every access reorders the internal linked list.  Access here is
defined as a call to get(key).

The problem is that to handle element expiration, UtilCache must call
get(key) on LinkedHashMap.  This causes the key to be accessed, which
pushes it to the front of the linked list, and breaks the LRU contract.

The way to fix this is to switch UtilCache away from a polling
mechanism for expiration.  Instead, a DelayQueue can be used, where
every single CacheLine is registered into a single, static DelayQueue,
and a thread is started that is always polling from that.  When an
item is returned from the poll, it removes it from it's containing cache.

This is the only way I see to get UtilCache make to being a proper LRU
system.

Reply via email to