Perhaps I'm being a bit dim, but ...

Why store the Property as a key and a value both?  Just store "" as the
value.  You can still get a list of all the cached Property objects by
calling keySet().  The entries in the Set returned may be WeakReference
objects, but that's easily dealt with.  

Just my 2 cents.

-- Mark C. Allman,
PMP
-- Allman
Professional
Consulting, Inc.
-- 617-947-4263
--
www.allmanpc.com











On Fri, 2007-07-20 at 14:53 +0100, Adrian Cumiskey wrote:

> Taking a look at the code and reading the spec :-
> 
> public class PropertyCache {
> 
>      private Map propCache = Collections.synchronizedMap(new WeakHashMap());
> 
> 
>      /**
>       *  Checks if the given property is present in the cache - if so, 
> returns
>       *  a reference to the cached value. Otherwise the given object is 
> added
>       *  to the cache and returned.
>       *  @param obj
>       *  @return the cached instance
>       */
>      public Property fetch(Property prop) {
> 
>          Property cacheEntry = (Property) propCache.get(prop);
>          if (cacheEntry != null) {
>              return cacheEntry;
>          } else {
>              propCache.put(prop, prop);
>              return prop;
>          }
>      }
> }
> 
> "Implementation note: The value objects in a WeakHashMap are held by 
> ordinary strong references. Thus care should be taken to ensure that 
> value objects do not strongly refer to their own keys, either directly 
> or indirectly, since that will prevent the keys from being discarded. 
> Note that a value object may refer indirectly to its key via the 
> WeakHashMap itself; that is, a value object may strongly refer to some 
> other key object whose associated value object, in turn, strongly refers 
> to the key of the first value object. One way to deal with this is to 
> wrap values themselves within WeakReferences before inserting, as in: 
> m.put(key, new WeakReference(value)), and then unwrapping upon each get."
> 
> I have to agree with Jeremias, the value does need to be wrapped in a 
> WeakReference object when it is put() in the PropertyCache as the value 
> reference will be held as a strong reference as it directly holds the 
> same reference value as its key.
> 
> This patch should single line patch should fix it.
> 
> -- snip --
> Index: src/java/org/apache/fop/fo/properties/PropertyCache.java
> ===================================================================
> --- src/java/org/apache/fop/fo/properties/PropertyCache.java 
> (revision 555659)
> +++ src/java/org/apache/fop/fo/properties/PropertyCache.java    (working 
> copy)
> @@ -19,6 +19,7 @@
> 
>   package org.apache.fop.fo.properties;
> 
> +import java.lang.ref.WeakReference;
>   import java.util.Collections;
>   import java.util.Map;
>   import java.util.WeakHashMap;
> @@ -48,7 +49,7 @@
>           if (cacheEntry != null) {
>               return cacheEntry;
>           } else {
> -            propCache.put(prop, prop);
> +            propCache.put(prop, new WeakReference(prop));
>               return prop;
>           }
>       }
> -- snip --
> 
> 
> Adrian.
> 
> Chris Bowditch wrote:
> > Jeremias Maerki wrote:
> > 
> >> On 20.07.2007 12:51:33 Chris Bowditch wrote:
> >>
> >>> Jeremias Maerki wrote:
> >>>
> >>>
> >>>> On 20.07.2007 11:52:15 Andreas L Delmelle wrote:
> >>>
> >>> <snip/>
> >>>
> >>>>>> In addition to that there was a bug in FixedLength.equals() that made
> >>>>>> the caching effect-less:
> >>>>>> http://svn.apache.org/viewvc?view=rev&rev=557934
> >>>>>
> >>>>> That was the most likely cause. The equals() method returning 
> >>>>> false  because of this, would keep on creating separate instances.
> >>>>> How they would be leaked into a subsequent run is not quite clear 
> >>>>> to  me, though...
> >>>>
> >>>>
> >>>> Because of the bug in PropertyCache. The two bugs just add to each 
> >>>> other.
> >>>
> >>> Thanks for spotting this bug in FixedLength.equals(). I rebuilt 
> >>> fop.jar and started a fresh profiling session. After 5000 renderings 
> >>> with only 16Mb the heap is staying around 3Mb. The number of 
> >>> FixedLength and WeakHashMap$entry object is staying fixed at around 
> >>> 300. Hip Hip Hooray!!!
> >>
> >>
> >> But you're running the same document over and over again, right? In that
> >> case, the WeakHashMap doesn't grow because the cached instances are
> >> always reused. That doesn't address the fact that the instances are
> >> still not releasable. The memory leak is still there. That's why it's so
> >> extremely important to be so damn careful about using static variables.
> > 
> > You are right of course. So if we ran lots of different documents with a 
> > very high number of variations in FixedLength then the memory leak still 
> > exists. It does sound to me from what you've been saying about the 
> > WekHashMap that more work in this area is still needed.
> > 
> > <snip/>
> > 
> > Chris
> > 
> > 
> > 
> 




Reply via email to