Any experts on java.lang.ref, or implementors of a performant SoftCache?

I am currently trying to implement a Cache whereby thevalues can be GC-d if they are not strongly referenced elsewhere. My cached Objects have aprimaryKey, to which they have a strong reference (and which will provide the key for the Cache). I have created aMap implementation,SoftValueHashMap, for the Cache which has an internalWeakHashMap. When adding values to the underlying weakMap, the values are placed insideSoftReference objects. My thinking was that when the values are no longer Strongly reachable theSoftReferences could be cleared. This in turn will enable the WeakKeys in theWeakHashMap to be cleared (as the keys would then become only WeaklyReachable).

Although this implementation is more complicated than just having a normalHashMap with (say) SoftlyReachable values, that particular method of providing a softly-valued Cache is not scalable as one has to periodically iterate through the whole Map's values in search of cleared references.

TheSoftValueHashMap therefore has a directWeakReference to theprimaryKey, and aSoftReference to the value which in turn has a Strong reference to theprimaryKey. It is unclear (to me, anyway) from the various documentation whether theprimaryKey is softly or weakly reachable, but I presume that the answer is "SoftlyReachable". The cached value is certainly Softly reachable. This is the behaviour I see when I inspect the Cache using an IDE:

1. The WeakKeys in theWeakHashMap seem to have their referents as null, but the underlyingprimaryKey objects have not been finalized.

2. TheSoftReference values in the WeakHashMap are intact, they have not had their referents cleared and these referents still internally reference theirprimaryKeys.

3. The cached values never seem to be GC-d, they are certainly never finalized even when the VM runs out of memory.

My questions are:

i). How can the WeakKey objects wrapping theprimaryKeys indicate that theprimaryKeys have been GC-d when, they have not?

ii). Why are my SoftKey objects which wrap the values not being cleared, even when system memory is low?

iii). Even when I make theprimaryKey only softly reachable from the cached value, why does the VM still go out of memory before doing any GC?

I'd be glad to post source code if anyone is interested.

[2506 byte] By [oxbow_lakesa] at [2007-9-19]
# 1

Hi,

there are some examples :

http//developer.java.sun.com/developer/technicalArticles/ALT/RefObj/

http//www.javaworld.com/javaworld/javatips/jw-javatip79.html

http//www.javaworld.com/javaworld/javatips/jw-javatip75.html

http//www.artima.com/insidejvm/ed2/ch09GarbageCollection01.html

gusseva at 2007-7-8 > top of java,Core,Core APIs...
# 2

Are you sure you need a internal WeakHashMap? Since it is ok to keep strong reference to your keys, something simple like this may be sufficient for your purpose.

public class SoftValueHashMap extends HashMap {

private RefrenceQueue rq = new ReferenceQueue();

//for simplicity's sake I am not implementing these two

public Set entrySet() {

throw new UnsupportedOperationException("not implemented");

}

public Collection values() {

throw new UnsupportedOperationException("not implemented");

}

public boolean containsValue(Object val) {

return containsValue(new SoftValue(val));

}

public void put(Object key, Object val) {

SoftValue sv = null;

while((sv = (SoftValue)rq.poll()) != null) {

remove(sv.getKey());

}

put(key, new SoftValue(val));

}

class SoftValue extends SoftReference{

private Object key;

public SoftValue(Object referent, ReferenceQueue q, Object key) {

super(referene, q);

this.key = key;

}

public Object getKey() {

return key;

}

public boolean equals(Object obj) {

return get().equals(obj);

}

}

}

zakariahqa at 2007-7-8 > top of java,Core,Core APIs...
# 3

> > class SoftValue extends SoftReference{

>private Object key;

>public SoftValue(Object referent, ReferenceQueue q,

>Object key) {

>super(referene, q);

>this.key = key;

>}

>public Object getKey() {

>return key;

>}

> }

>

I can't believe I didn't spot that one - of course you are correct! My reasoning for using an Internal WeakHashMap was that I didn't see how I could get the key back from my value reference. What a dope!

oxbow_lakesa at 2007-7-8 > top of java,Core,Core APIs...
# 4
I dont get it. What good is it to be able to get the key from the value?
dnoyeBa at 2007-7-8 > top of java,Core,Core APIs...
# 5
Well, for the SoftValueHashMap: how about extending WeakHashMap instead of HashMap?then as soon as the SoftValue is beeing garbage collectet the strong reference to the WeakReferecenced key disapears and eventaully the key itself will be garbage collected too , right ?Bodo
bteichmanna at 2007-7-8 > top of java,Core,Core APIs...