]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Bugzilla 46319:
authorAndreas L. Delmelle <adelmelle@apache.org>
Mon, 8 Dec 2008 18:54:16 +0000 (18:54 +0000)
committerAndreas L. Delmelle <adelmelle@apache.org>
Mon, 8 Dec 2008 18:54:16 +0000 (18:54 +0000)
Fixed a memory-leak in Marker.MarkerAttribute, where an instance was used as both key and value
in a WeakHashMap, effectively neutralizing the benefit of using WeakReferences.
Solved by extending PropertyCache to work for MarkerAttributes as well.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@724444 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/fo/flow/Marker.java
src/java/org/apache/fop/fo/properties/PropertyCache.java
status.xml

index 1e8b352bbf793d5a68d422d0c101a7e19b801288..01863c0c74fc34807e6392bff7edb532373eb0d5 100644 (file)
@@ -34,6 +34,7 @@ import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.PropertyListMaker;
 import org.apache.fop.fo.ValidationException;
 import org.apache.fop.fo.properties.Property;
+import org.apache.fop.fo.properties.PropertyCache;
 
 /**
  * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_marker">
@@ -334,10 +335,10 @@ public class Marker extends FObjMixed {
     }
 
     /** Convenience inner class */
-    private static final class MarkerAttribute {
+    public static final class MarkerAttribute {
 
-        private static Map attributeCache =
-            Collections.synchronizedMap(new java.util.WeakHashMap());
+        private static PropertyCache attributeCache =
+                new PropertyCache(MarkerAttribute.class);
 
         protected String namespace;
         protected String qname;
@@ -373,18 +374,26 @@ public class Marker extends FObjMixed {
         private static MarkerAttribute getInstance(
                                             String namespace, String qname,
                                             String name, String value) {
-            MarkerAttribute newInstance =
-                new MarkerAttribute(namespace, qname, name, value);
-            if (attributeCache.containsKey(newInstance)) {
-                return (MarkerAttribute) attributeCache.get(newInstance);
-            } else {
-                attributeCache.put(newInstance, newInstance);
-                return newInstance;
-            }
+            return attributeCache.fetch(
+                    new MarkerAttribute(namespace, qname, name, value));
+        }
+
+        /** {@inheritDoc} */
+        public int hashCode() {
+            int hash = 17;
+            hash = (37 * hash) + (this.namespace == null ? 0 : this.namespace.hashCode());
+            hash = (37 * hash) + (this.qname == null ? 0 : this.qname.hashCode());
+            hash = (37 * hash) + (this.name == null ? 0 : this.name.hashCode());
+            hash = (37 * hash) + (this.value == null ? 0 : this.value.hashCode());
+            return hash;
         }
 
         /** {@inheritDoc} */
         public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+
             if (o instanceof MarkerAttribute) {
                 MarkerAttribute attr = (MarkerAttribute) o;
                 return ((attr.namespace == this.namespace)
index d472b574c5ca7f24d1ca2fbd886aa1f2000597c7..dc9abb0231f5dfb9a7abb76621cc1171df28b0d4 100644 (file)
@@ -19,6 +19,8 @@
 
 package org.apache.fop.fo.properties;
 
+import org.apache.fop.fo.flow.Marker;
+
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 
@@ -53,7 +55,7 @@ public final class PropertyCache {
 
     private Class runtimeType;
 
-    private boolean[] votesForRehash = new boolean[SEGMENT_COUNT];
+    private final boolean[] votesForRehash = new boolean[SEGMENT_COUNT];
 
     /* same hash function as used by java.util.HashMap */
     private static int hash(Object x) {
@@ -381,6 +383,19 @@ public final class PropertyCache {
         return (CommonBorderPaddingBackground.BorderInfo) fetch((Object) bi);
     }
 
+    /**
+     *  Checks if the given {@link Marker.MarkerAttribute} is present
+     *  in the cache - if so, returns a reference to the cached instance.
+     *  Otherwise the given object is added to the cache and returned.
+     *
+     *  @param ma the MarkerAttribute instance to check for
+     *  @return the cached instance
+     */
+    public Marker.MarkerAttribute fetch(
+            Marker.MarkerAttribute ma) {
+        return (Marker.MarkerAttribute) fetch((Object) ma);
+    }
+
     /** {@inheritDoc} */
     public String toString() {
         return super.toString() + "[runtimeType=" + this.runtimeType + "]";
index b2e37dd33a6381a2131cd6206f00bdd0b26bece8..c7d030e8037886932ccfb04753b0bfdad899f26b 100644 (file)
 
   <changes>
     <release version="FOP Trunk" date="TBD">
+      <action context="Code" dev="AD" type="fix" fixes-bug="46319">
+        Fixed a memory-leak in Marker.MarkerAttribute, where an instance was used both as key and value in
+        a WeakHashMap, effectively neutralizing the benefit of using WeakReferences. Solved by extending
+        PropertyCache to work for MarkerAttributes as well.
+      </action>
       <action context="Renderers" dev="JM" type="fix" fixed-bug="46360">
         Fixed a multi-threading issue when rendering SVG.
       </action>