aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorAndreas L. Delmelle <adelmelle@apache.org>2008-12-08 18:54:16 +0000
committerAndreas L. Delmelle <adelmelle@apache.org>2008-12-08 18:54:16 +0000
commitf9d4720b99f5e0fb423b097d7207dfab446d911c (patch)
tree731a001eced7bde7f48909a04fa4c0163ff611af /src/java
parent607aeaa986fbf0ecbc55684dad0b3286613f56dd (diff)
downloadxmlgraphics-fop-f9d4720b99f5e0fb423b097d7207dfab446d911c.tar.gz
xmlgraphics-fop-f9d4720b99f5e0fb423b097d7207dfab446d911c.zip
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
Diffstat (limited to 'src/java')
-rw-r--r--src/java/org/apache/fop/fo/flow/Marker.java31
-rw-r--r--src/java/org/apache/fop/fo/properties/PropertyCache.java17
2 files changed, 36 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 <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)
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 + "]";