Ard Schrijvers wrote:
the StoreJanitorImpl is capable of deleting the entire memory part of the 
EHCache when JVM is low on memory: The StoreJanitorImpl counts the number of 
keys in cache, and multiplies this with the percent_to_free, to calculate the 
number of items to delete from cache...more or less like

final List keys = this.cache.getKeysNoDuplicateCheck();
final Serializable key = (Serializable) keys.get(0);
this.cache.remove(key);

Now, the fact that getKeysNoDuplicateCheck() return a list of ALL keys 
(memoryStore + diskStore), where keys.get(0) is always in the memoryStore 
because of

public final synchronized List getKeysNoDuplicateCheck() throws 
IllegalStateException {
        checkStatus();
        ArrayList allKeys = new ArrayList();
        List memoryKeySet = Arrays.asList(memoryStore.getKeyArray());
        allKeys.addAll(memoryKeySet);
        if (overflowToDisk) {
            List diskKeySet = Arrays.asList(diskStore.getKeyArray());
            allKeys.addAll(diskKeySet);
        }
        return allKeys;
    }

AND the fact that for the number of keys to delete, store.size() [store.size() 
= memoryStore.getKeyArray() + diskStore.getKeyArray() ] is used, it is quite 
likely you end up with an example like the following:

1) JVM memory = low
2) percent_to_free = 10%
3) store.size() = 10.000 (though the memoryStore part = 1000 because maxobjects 
is set to 1000)

This implies, that the StoreJanitor removes the first 1000 cachekeys + 
responses, i.e, my entire memoryStore.

<snip/>

WDYT about the StoreJanitor only trying to free memory from EHDefaultStore AND 
do this by adding keys

Clearly, all your problems stem from the faulty implementation of Store abstraction by the EHDefaultStore. As such, it would just make sense fixing up EHDefaultStore implementation, starting with marked TODO items, rather than breaking StoreJanitor.

Alternatively, you can consider not using EHDefaultStore at all, by choosing any other implementation.


Vadim

Reply via email to