From f9d4720b99f5e0fb423b097d7207dfab446d911c Mon Sep 17 00:00:00 2001 From: "Andreas L. Delmelle" Date: Mon, 8 Dec 2008 18:54:16 +0000 Subject: [PATCH] Bugzilla 46319: 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 | 31 ++++++++++++------- .../fop/fo/properties/PropertyCache.java | 17 +++++++++- status.xml | 5 +++ 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/java/org/apache/fop/fo/flow/Marker.java b/src/java/org/apache/fop/fo/flow/Marker.java index 1e8b352bb..01863c0c7 100644 --- a/src/java/org/apache/fop/fo/flow/Marker.java +++ b/src/java/org/apache/fop/fo/flow/Marker.java @@ -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 @@ -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) diff --git a/src/java/org/apache/fop/fo/properties/PropertyCache.java b/src/java/org/apache/fop/fo/properties/PropertyCache.java index d472b574c..dc9abb023 100644 --- a/src/java/org/apache/fop/fo/properties/PropertyCache.java +++ b/src/java/org/apache/fop/fo/properties/PropertyCache.java @@ -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 + "]"; diff --git a/status.xml b/status.xml index b2e37dd33..c7d030e80 100644 --- a/status.xml +++ b/status.xml @@ -53,6 +53,11 @@ + + 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. + Fixed a multi-threading issue when rendering SVG. -- 2.39.5