AW: [OJB-developers] ObjectCache and IdentityFactory]
Brought to you by:
thma
From: Mahler T. <tho...@it...> - 2002-03-26 09:20:03
|
Hi Florian, > Hi Thomas, <snip> > > I'm quite sure about the memory leak. SoftReference objects > behave like all > other objects, i.e. they are collected when there are no > references to the > objects left. Lets look at ObjectCacheImpl: > > public void cache(Identity oid, Object obj) > { > if ((obj != null)) > { > SoftReference ref = new SoftReference(obj); > objectTable.put(oid.toString(), ref); > } > } > > This creates a new SoftReference with the object to cache > being the referent > of the SoftReference. The referent is subject to special > handling by the GC, > i.e. it can be collected if there are not other references to obj. Ahh, now I get your point. We'll have to remove the SoftReferences from the objectTable too, to make them collectable! I did not care about that in my original implementation. > The following code (in lookup) removes entries of the > Hashtable where the > values have been collected: > > if (ref != null) > { > obj = ref.get(); > if (obj == null) > { > gcCount++; > objectTable.remove(oid); > } > } Yes, exactly! > If the entry is processed by this code the SoftReference will be gc'd > because there is no reference left to it (normal gc behaviour). OK. > The problem is, when you have entries in the Hashtable that, > at some point > in time, get collected, but there is never ever again a lookup of the > object. In this case the entry in the Hashtable remains and > therefore a > couple of objects (Identity, Map.Entry, SoftReference) remain > in memory. Ooops, you are right, this will happen. We have to ensure that all obsolete Softreferences are deleted from the map! > Other implementations of such caches or WeakHashMap/SoftHashMaps work > differently. They maintain an instance of > java.lang.ref.ReferenceQueue and > pass this instance to all created SoftReference/WeakReference objects. > Whenever the referent of a Soft/WeakReference is collected, the > SoftReference/WeakReference is added to the ReferenceQueue. > > Now, whenever you modify the map (by put, remove etc.) the > ReferenceQueue is > processed and the entries are removed. This leads to another > typical issue > in such implementations: Usually the KEY of the map is > encapsulated in a > Soft/WeakReference. This is done to make cleaning up > efficient, because you > can only access a map by keys, but has the disadvantage that > not the objects > that might be larger in size (usually the value) are > collected if memory is > running low. > > There are some other disadvantages with this approach (like > entries never > get thrown out when you do not modify a map over some time, > unpredictable > processing time of modification operations), and in general > the more I look > into these implementations the more I get the feeling that all of them > contain somewhat ugly hacks that prevent them from being a > reliable and > calculable solution for a cache (i.e. efficient lookup, efficient in > modification and retrieval of the cache, calculable and > constant time of > lookup and modification, ...) > Here my idea: We can check if a SoftReference is valid by (ref.get() != null) It won't be difficult to write a method that traverses the complete objectTable and removes all invalid Sofreferences. This cleanup method could be called every 1000 calls of lookup or so... What do you think? > best regards, > Florian > |