How to evict a node when all its children have been evicted?
nfilotto Jan 21, 2010 10:40 AMHi All,
Since the last past days, I have been working on finding a memory leak in my program. I finally identified it, in fact it is due to the fact that in JBC when all the sub nodes of a JBC node are evicted, the parent node is never evicted even if it has not been declared resident.
Let's take a concrete example
We assume that I have the following configuration
{code}
<eviction wakeUpInterval="5000">
<default algorithmClass="org.jboss.cache.eviction.FIFOAlgorithm" eventQueueSize="1000000">
<property name="maxNodes" value="1" />
</default>
</eviction>
{code}
if I first call cache.put(Fqn.fromElements("1","1"),key,value)
If I then call cache.put(Fqn.fromElements("2"),key,value), the node "/1/1" is evicted but its parent node "/1" is not evicted
If I then call cache.put(Fqn.fromElements("3"),key,value), the node "/2" is evicted but node "/1" is still present.
This zombie node (i.e. node "/1") is the cause of my memory leak. So my question is, is there a way to make JBC evicts those kind of nodes?
To limit the memory leak, I implemented a EvictionActionPolicy, but I would like to know if there is a better solution. If I don't have any other way, could you check my code below and tell me how I could improve it, because up to now, it fixes about 95% of the memory leak but it seems that it doesn't work 100% of the time:
{code}
public class MyEvictionActionPolicy implements EvictionActionPolicy
{
Cache<?, ?> cache;
private static final Log log = LogFactory.getLog(DefaultEvictionActionPolicy.class);
public void setCache(Cache<?, ?> cache)
{
this.cache = cache;
}
public boolean evict(Fqn fqn)
{
boolean result;
try
{
if (log.isTraceEnabled()) log.trace("Evicting Fqn " + fqn);
cache.evict(fqn);
result = true;
}
catch (Exception e)
{
if (log.isDebugEnabled()) log.debug("Unable to evict " + fqn, e);
result = false;
}
if (fqn.size() != 3)
{
return result;
}
try
{
Fqn parentFqn = fqn.getParent();
if (parentFqn.get(0).equals(JBossCacheWorkspaceStorageCache.CHILD_NODES) || parentFqn.get(0).equals(
JBossCacheWorkspaceStorageCache.CHILD_PROPS))
{
// The expected data structure is of type $CHILD_NODES/${node-id}/${sub-node-name} or
// $CHILD_PROPS/${node-id}/${sub-property-name}
Set<Object> names = cache.getChildrenNames(parentFqn);
if (names.isEmpty() || (names.size() == 1 && names.contains(fqn.get(2))))
{
if (log.isTraceEnabled()) log.trace("Evicting Fqn " + fqn);
cache.evict(parentFqn);
}
}
}
catch (Exception e)
{
if (log.isDebugEnabled()) log.debug("Unable to evict " + fqn, e);
}
return result;
}
}
{code}
Thank you in advance for your help,
BR,
Nicolas Filotto