

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
34 messages in org.codehaus.groovy.devRe: [groovy-dev] Re: [groovy-user] Me...| From | Sent On | Attachments |
|---|---|---|
| Alex Tkachman | Oct 16, 2008 2:30 pm | |
| Alex Tkachman | Oct 16, 2008 3:17 pm | |
| Jochen Theodorou | Oct 16, 2008 3:49 pm | |
| Tim Quinn | Oct 16, 2008 4:15 pm | |
| Alexander Veit | Oct 16, 2008 4:34 pm | |
| Jochen Theodorou | Oct 16, 2008 4:43 pm | |
| Tim Quinn | Oct 16, 2008 5:28 pm | |
| Jochen Theodorou | Oct 17, 2008 6:35 am | |
| Alex Tkachman | Oct 17, 2008 6:44 am | |
| Graeme Rocher | Oct 17, 2008 6:54 am | |
| Jochen Theodorou | Oct 17, 2008 7:05 am | |
| Graeme Rocher | Oct 17, 2008 7:14 am | |
| alex...@gmail.com | Oct 17, 2008 7:30 am | |
| Jochen Theodorou | Oct 17, 2008 7:36 am | |
| Alex Tkachman | Oct 17, 2008 9:51 am | |
| Jochen Theodorou | Oct 22, 2008 5:27 am | |
| Alex Tkachman | Oct 22, 2008 5:37 am | |
| Jochen Theodorou | Oct 22, 2008 6:05 am | |
| Alex Tkachman | Oct 22, 2008 6:08 am | |
| Jochen Theodorou | Oct 22, 2008 6:18 am | .zip |
| Alex Tkachman | Oct 22, 2008 6:32 am | |
| Jochen Theodorou | Oct 22, 2008 7:06 am | |
| Guillaume Laforge | Oct 22, 2008 7:08 am | |
| Alex Tkachman | Oct 22, 2008 7:11 am | |
| Guillaume Laforge | Oct 22, 2008 7:21 am | |
| Jochen Theodorou | Oct 22, 2008 7:22 am | |
| Jochen Theodorou | Oct 22, 2008 7:39 am | |
| Jochen Theodorou | Oct 22, 2008 7:41 am | |
| Alex Tkachman | Oct 22, 2008 9:16 am | |
| Jochen Theodorou | Oct 22, 2008 10:11 am | |
| Jochen Theodorou | Oct 22, 2008 11:24 am | |
| Alex Tkachman | Oct 22, 2008 11:48 am | |
| Jochen Theodorou | Oct 22, 2008 2:07 pm | |
| Jochen Theodorou | Dec 22, 2008 12:52 pm |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | Re: [groovy-dev] Re: [groovy-user] Memory leaks in Groovy | Actions... |
|---|---|---|
| From: | Jochen Theodorou (blac...@gmx.org) | |
| Date: | Oct 22, 2008 6:05:03 am | |
| List: | org.codehaus.groovy.dev | |
Alex Tkachman schrieb:
If you would like (think it will help) I can review the code before you commit.
well, sure, but it is of course a big patch. I attached the svn diff output in src to this post. the strong meta class tracking is atm commented out
hope this works for you
bye blackdrag
-- Jochen "blackdrag" Theodorou The Groovy Project Tech Lead (http://groovy.codehaus.org) http://blackdragsview.blogspot.com/ http://www.g2one.com/
Index: test/org/codehaus/groovy/reflection/WeakMapTest.groovy
===================================================================
--- test/org/codehaus/groovy/reflection/WeakMapTest.groovy (Revision 13791)
+++ test/org/codehaus/groovy/reflection/WeakMapTest.groovy (Arbeitskopie)
@@ -27,8 +27,7 @@
if (i % 50 == 0)
shell = null
System.gc ()
- println "${i} ${ReflectionCache.assignableMap.size()}
${ReflectionCache.assignableMap.fullSize()} ${ClassInfo.size()}
${ClassInfo.fullSize()}"
- }
+ }
if (shell != null) shell.classLoader.clearCache() Index: main/groovy/ui/Console.groovy =================================================================== --- main/groovy/ui/Console.groovy (Revision 13791) +++ main/groovy/ui/Console.groovy (Arbeitskopie) @@ -216,7 +216,7 @@
bindResults()
- // stitch some actions togeather
+ // stitch some actions together
swing.bind(source:swing.inputEditor.undoAction,
sourceProperty:'enabled', target:swing.undoAction, targetProperty:'enabled')
swing.bind(source:swing.inputEditor.redoAction,
sourceProperty:'enabled', target:swing.redoAction, targetProperty:'enabled')
Index:
main/org/codehaus/groovy/runtime/metaclass/ThreadManagedMetaBeanProperty.java
===================================================================
---
main/org/codehaus/groovy/runtime/metaclass/ThreadManagedMetaBeanProperty.java
(Revision 13791)
+++
main/org/codehaus/groovy/runtime/metaclass/ThreadManagedMetaBeanProperty.java
(Arbeitskopie)
@@ -21,8 +21,12 @@
import groovy.lang.MetaMethod;
import org.codehaus.groovy.reflection.CachedClass;
import org.codehaus.groovy.reflection.ReflectionCache;
-import org.codehaus.groovy.util.ConcurrentWeakMap;
+import org.codehaus.groovy.util.ManagedConcurrentMap;
+import org.codehaus.groovy.util.ReferenceManager;
+import org.codehaus.groovy.util.ReferenceType;
+import org.codehaus.groovy.util.ManagedReference.ReferenceBundle;
+import java.lang.ref.ReferenceQueue; import java.lang.reflect.Modifier; import java.util.concurrent.ConcurrentHashMap;
@@ -40,15 +44,23 @@
*/
public class ThreadManagedMetaBeanProperty extends MetaBeanProperty {
private static final CachedClass[] ZERO_ARGUMENT_LIST = new CachedClass[0];
- private static final ConcurrentHashMap<String,ConcurrentWeakMap>
propName2Map = new ConcurrentHashMap<String, ConcurrentWeakMap>();
+ private static final ConcurrentHashMap<String,ManagedConcurrentMap>
propName2Map = new ConcurrentHashMap<String, ManagedConcurrentMap>();
- private final ConcurrentWeakMap instance2Prop; + private final ManagedConcurrentMap instance2Prop;
private Class declaringClass;
private ThreadBoundGetter getter;
private ThreadBoundSetter setter;
private Object initialValue;
private Closure initialValueCreator;
+
+ private final static ReferenceBundle softBundle;
+ static {
+ ReferenceQueue queue = new ReferenceQueue();
+ ReferenceManager callBack =
ReferenceManager.createCallBackedManager(queue);
+ ReferenceManager manager =
ReferenceManager.createThresholdedIdlingManager(queue, callBack, 200);
+ softBundle = new ReferenceBundle(manager, ReferenceType.SOFT);
+ }
/** * Retrieves the initial value of the ThreadBound property @@ -116,11 +128,11 @@ instance2Prop = getInstance2PropName(name); }
- private static ConcurrentWeakMap getInstance2PropName(String name) {
- ConcurrentWeakMap res = propName2Map.get(name);
+ private static ManagedConcurrentMap getInstance2PropName(String name) {
+ ManagedConcurrentMap res = propName2Map.get(name);
if (res == null) {
- res = new ConcurrentWeakMap();
- ConcurrentWeakMap ores = propName2Map.putIfAbsent(name, res);
+ res = new ManagedConcurrentMap(softBundle);
+ ManagedConcurrentMap ores = propName2Map.putIfAbsent(name, res);
if (ores != null)
return ores;
}
@@ -177,7 +189,7 @@
* @see groovy.lang.MetaMethod#invoke(java.lang.Object,
java.lang.Object[])
*/
public Object invoke(Object object, Object[] arguments) {
- return
((ConcurrentWeakMap.EntryWithValue)instance2Prop.getOrPut(object,
getInitialValue())).getValue();
+ return
((ManagedConcurrentMap.EntryWithValue)instance2Prop.getOrPut(object,
getInitialValue())).getValue();
}
}
Index: main/org/codehaus/groovy/runtime/metaclass/MetaClassRegistryImpl.java
===================================================================
--- main/org/codehaus/groovy/runtime/metaclass/MetaClassRegistryImpl.java
(Revision 13791)
+++ main/org/codehaus/groovy/runtime/metaclass/MetaClassRegistryImpl.java
(Arbeitskopie)
@@ -23,8 +23,6 @@
import org.codehaus.groovy.vmplugin.VMPluginFactory;
import org.codehaus.groovy.util.FastArray;
-import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -32,7 +30,6 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger;
/** * A registry of MetaClass instances which caches introspection & @@ -55,7 +52,7 @@
private LinkedList changeListenerList = new LinkedList(); private LinkedList metaClassInfo = new LinkedList(); - private ReferenceQueue queue = new ReferenceQueue(); + //TODO: private ReferenceQueue queue = new ReferenceQueue();
public static final int LOAD_DEFAULT = 0; public static final int DONT_LOAD_DEFAULT = 1; @@ -109,9 +106,9 @@
addMetaClassRegistryChangeEventListener(new
MetaClassRegistryChangeEventListener(){
public void updateConstantMetaClass(MetaClassRegistryChangeEvent
cmcu) {
- synchronized (metaClassInfo) {
- metaClassInfo.add(new
WeakReference(cmcu.getNewMetaClass(),queue));
- }
+//TODO: synchronized (metaClassInfo) {
+// metaClassInfo.add(new
WeakReference(cmcu.getNewMetaClass(),queue));
+// }
}
});
}
@@ -138,7 +135,7 @@
CachedMethod[] methods =
ReflectionCache.getCachedClass(theClass).getMethods();
if (useMethodrapper) {
- // Here we instanciate objects representing MetaMethods for DGM
methods.
+ // Here we instantiate objects representing MetaMethods for DGM
methods.
// Calls for such meta methods done without reflection, so more
effectively.
// It gives 7-8% improvement for benchmarks involving just several
ariphmetic operations
for (int i = 0; ; ++i) {
@@ -225,7 +222,7 @@
info.unlock();
}
- if (oldMc==mc) fireConstantMetaClassUpdate(theClass,newMc); + if (oldMc!=mc) fireConstantMetaClassUpdate(theClass,newMc); }
public void removeMetaClass(Class theClass) { @@ -314,21 +311,21 @@
private void cleanMetaClassList() { - boolean hasCollectedEntries=false; - java.lang.ref.Reference r=null; - while ((r=queue.poll())!=null) { - r.clear(); - hasCollectedEntries=true; - } - - if (!hasCollectedEntries) return; - - for (Iterator it = metaClassInfo.iterator(); it.hasNext();) { - WeakReference ref = (WeakReference) it.next(); - if (ref.get()!=null) continue; - it.remove(); - ref.clear(); - } +//TODO: boolean hasCollectedEntries=false; +// java.lang.ref.Reference r=null; +// while ((r=queue.poll())!=null) { +// r.clear(); +// hasCollectedEntries=true; +// } +// +// if (!hasCollectedEntries) return; +// +// for (Iterator it = metaClassInfo.iterator(); it.hasNext();) { +// WeakReference ref = (WeakReference) it.next(); +// if (ref.get()!=null) continue; +// it.remove(); +// ref.clear(); +// } }
/**
@@ -395,55 +392,56 @@
* @return the iterator.
*/
public Iterator iterator() {
- final WeakReference[] refs;
- synchronized (metaClassInfo) {
- cleanMetaClassList();
- refs = (WeakReference[]) metaClassInfo.toArray(new
WeakReference[0]);
- }
-
- return new Iterator() {
- // index inn the ref array
- private int index=0;
- // the current meta class
- private MetaClass currentMeta;
- // used to ensure that hasNext has been called
- private boolean hasNextCalled=false;
- // the cached hasNext call value
- private boolean hasNext=false;
-
- public boolean hasNext() {
- if (hasNextCalled) return hasNext;
- hasNextCalled = true;
- hasNext=true;
-
- // currentMeta==null means the entry might have been
- // collected already, we skip these.
- currentMeta=null;
- while (currentMeta==null && index<refs.length) {
- currentMeta = (MetaClass) refs[index].get();
- index++;
- }
- hasNext=currentMeta!=null;
- return hasNext;
- }
-
- private void ensureNext() {
- // we ensure that hasNext has been called before
- // next is called
- hasNext();
- hasNextCalled=false;
- }
-
- public Object next() {
- ensureNext();
- return currentMeta;
- }
-
- public void remove() {
- ensureNext();
- setMetaClass(currentMeta.getTheClass(),currentMeta,null);
- currentMeta=null;
- }
- };
+ return null;
+//TODO: final WeakReference[] refs;
+// synchronized (metaClassInfo) {
+// cleanMetaClassList();
+// refs = (WeakReference[]) metaClassInfo.toArray(new
WeakReference[0]);
+// }
+//
+// return new Iterator() {
+// // index inn the ref array
+// private int index=0;
+// // the current meta class
+// private MetaClass currentMeta;
+// // used to ensure that hasNext has been called
+// private boolean hasNextCalled=false;
+// // the cached hasNext call value
+// private boolean hasNext=false;
+//
+// public boolean hasNext() {
+// if (hasNextCalled) return hasNext;
+// hasNextCalled = true;
+// hasNext=true;
+//
+// // currentMeta==null means the entry might have been
+// // collected already, we skip these.
+// currentMeta=null;
+// while (currentMeta==null && index<refs.length) {
+// currentMeta = (MetaClass) refs[index].get();
+// index++;
+// }
+// hasNext=currentMeta!=null;
+// return hasNext;
+// }
+//
+// private void ensureNext() {
+// // we ensure that hasNext has been called before
+// // next is called
+// hasNext();
+// hasNextCalled=false;
+// }
+//
+// public Object next() {
+// ensureNext();
+// return currentMeta;
+// }
+//
+// public void remove() {
+// ensureNext();
+// setMetaClass(currentMeta.getTheClass(),currentMeta,null);
+// currentMeta=null;
+// }
+// };
}
}
Index: main/org/codehaus/groovy/reflection/MixinInMetaClass.java
===================================================================
--- main/org/codehaus/groovy/reflection/MixinInMetaClass.java (Revision 13791)
+++ main/org/codehaus/groovy/reflection/MixinInMetaClass.java (Arbeitskopie)
@@ -3,6 +3,7 @@
import groovy.lang.*;
import java.lang.reflect.Modifier; +import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.WeakHashMap; import java.util.List; @@ -17,14 +18,26 @@ import org.codehaus.groovy.runtime.metaclass.MixedInMetaClass; import org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod; import org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaProperty; -import org.codehaus.groovy.util.ConcurrentWeakMap; +import org.codehaus.groovy.util.ManagedConcurrentMap; +import org.codehaus.groovy.util.ReferenceManager; +import org.codehaus.groovy.util.ReferenceType; +import org.codehaus.groovy.util.ManagedReference.ReferenceBundle;
-public class MixinInMetaClass extends ConcurrentWeakMap { +public class MixinInMetaClass extends ManagedConcurrentMap { final ExpandoMetaClass emc; final CachedClass mixinClass; final CachedConstructor constructor;
+ private static ReferenceBundle softBundle;
+ static {
+ ReferenceQueue queue = new ReferenceQueue();
+ ReferenceManager callBack =
ReferenceManager.createCallBackedManager(queue);
+ ReferenceManager manager =
ReferenceManager.createThresholdedIdlingManager(queue, callBack, 200);
+ softBundle = new ReferenceBundle(manager, ReferenceType.SOFT);
+ }
+
public MixinInMetaClass(ExpandoMetaClass emc, CachedClass mixinClass) {
+ super(softBundle);
this.emc = emc;
this.mixinClass = mixinClass;
Index: main/org/codehaus/groovy/reflection/ReflectionCache.java =================================================================== --- main/org/codehaus/groovy/reflection/ReflectionCache.java (Revision 13791) +++ main/org/codehaus/groovy/reflection/ReflectionCache.java (Arbeitskopie) @@ -16,7 +16,6 @@ package org.codehaus.groovy.reflection;
import org.codehaus.groovy.util.TripleKeyHashMap; -import org.codehaus.groovy.util.SoftDoubleKeyMap;
import java.util.HashMap; import java.util.Map; @@ -49,9 +48,7 @@ } return (String) mopNameEntry.value; } - - static SoftDoubleKeyMap assignableMap = new SoftDoubleKeyMap(); - + static final CachedClass STRING_CLASS = getCachedClass(String.class);
public static boolean isArray(Class klazz) { Index: main/org/codehaus/groovy/reflection/ClassInfo.java =================================================================== --- main/org/codehaus/groovy/reflection/ClassInfo.java (Revision 13791) +++ main/org/codehaus/groovy/reflection/ClassInfo.java (Arbeitskopie) @@ -19,6 +19,7 @@ import org.codehaus.groovy.reflection.stdclasses.*; import org.codehaus.groovy.util.*;
+import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.math.BigDecimal; import java.math.BigInteger; @@ -30,38 +31,44 @@ * * @author Alex.Tkachman */ -public class ClassInfo extends ConcurrentSoftMap.Entry<Class,ClassInfo> { +public class ClassInfo extends ManagedConcurrentMap.Entry<Class,ClassInfo> {
+ private static final HashSet<ClassInfo> modifiedExpandos = new
HashSet<ClassInfo>();
+
private final LazyCachedClassRef cachedClassRef;
+ private final LazyClassLoaderRef artifactClassLoader;
+ private final LockableObject lock = new LockableObject();
+ public final int hash;
+ private volatile int version;
+
private MetaClass strongMetaClass;
-
private SoftReference<MetaClass> weakMetaClass;
-
- private volatile int version;
-
- private final LazyClassLoaderRef artifactClassLoader;
-
- private static final HashSet<ClassInfo> modifiedExpandos = new
HashSet<ClassInfo>();
-
- private final LockableObject lock = new LockableObject();
-
MetaMethod[] dgmMetaMethods = CachedClass.EMPTY;
-
MetaMethod[] newMetaMethods = CachedClass.EMPTY;
+ private ManagedConcurrentMap perInstanceMetaClassMap;
+
+ private final static ReferenceBundle softBundle;
+ private final static ReferenceBundle perInstanceBundle;
+ static {
+ ReferenceQueue queue = new ReferenceQueue();
+ ReferenceManager callBack =
ReferenceManager.createCallBackedManager(queue);
+ ReferenceManager manager =
ReferenceManager.createThresholdedIdlingManager(queue, callBack, 500);
+ softBundle = new ReferenceBundle(manager, ReferenceType.SOFT);
+ perInstanceBundle = new ReferenceBundle(manager, ReferenceType.WEAK);
+ }
+ private static final ClassInfoSet globalClassSet = new
ClassInfoSet(softBundle);
+
- public final int hash; - private ConcurrentWeakMap perInstanceMetaClassMap; + ClassInfo(ManagedConcurrentMap.Segment segment, Class klazz, int hash) { + super (softBundle, segment, klazz, hash);
- ClassInfo(ConcurrentSoftMap.Segment segment, Class klazz, int hash) { - super (segment, klazz, hash); - if (ClassInfo.DebugRef.debug) new DebugRef(klazz);
this.hash = hash; - cachedClassRef = new LazyCachedClassRef(this); - artifactClassLoader = new LazyClassLoaderRef(this); + cachedClassRef = new LazyCachedClassRef(softBundle, this); + artifactClassLoader = new LazyClassLoaderRef(softBundle, this); }
public int getVersion() { @@ -88,8 +95,6 @@ return artifactClassLoader.get(); }
- private static final ClassInfoSet globalClassSet = new ClassInfoSet(); - public static ClassInfo getClassInfo (Class cls) { return localMap.get().get(cls); } @@ -188,8 +193,8 @@
public void finalizeRef() { setStrongMetaClass(null); - cachedClassRef.set(null); - artifactClassLoader.set(null); + cachedClassRef.clear(); + artifactClassLoader.clear();
super.finalizeRef(); } @@ -264,7 +269,7 @@
if (metaClass != null) {
if (perInstanceMetaClassMap == null)
- perInstanceMetaClassMap = new ConcurrentWeakMap ();
+ perInstanceMetaClassMap = new
ManagedConcurrentMap(perInstanceBundle);
perInstanceMetaClassMap.put(obj, metaClass); } @@ -279,18 +284,21 @@ return perInstanceMetaClassMap != null; }
- public static class ClassInfoSet extends ConcurrentSoftMap<Class,ClassInfo>
{
-
- public ClassInfoSet() {
+ public static class ClassInfoSet extends
ManagedConcurrentMap<Class,ClassInfo> {
+ public ClassInfoSet(ReferenceBundle bundle) {
+ super(bundle);
}
- protected Segment createSegment(int cap) {
- return new Segment(cap);
+ protected Segment createSegment(Object segmentInfo, int cap) {
+ ReferenceBundle bundle = (ReferenceBundle) segmentInfo;
+ if (bundle==null) throw new IllegalArgumentException("bundle must
not be null ");
+
+ return new Segment(bundle, cap);
}
- static final class Segment extends
ConcurrentSoftMap.Segment<Class,ClassInfo> {
- Segment(int initialCapacity) {
- super(initialCapacity);
+ static final class Segment extends
ManagedConcurrentMap.Segment<Class,ClassInfo> {
+ Segment(ReferenceBundle bundle, int initialCapacity) {
+ super(bundle, initialCapacity);
}
protected ClassInfo createEntry(Class key, int hash, ClassInfo
unused) {
@@ -371,10 +379,11 @@
}
};
- private static class LazyCachedClassRef extends
LazySoftReference<CachedClass> {
+ private static class LazyCachedClassRef extends LazyReference<CachedClass>
{
private final ClassInfo info;
- LazyCachedClassRef(ClassInfo info) { + LazyCachedClassRef(ReferenceBundle bundle, ClassInfo info) { + super(bundle); this.info = info; }
@@ -383,10 +392,11 @@ } }
- private static class LazyClassLoaderRef extends
LazySoftReference<ClassLoaderForClassArtifacts> {
+ private static class LazyClassLoaderRef extends
LazyReference<ClassLoaderForClassArtifacts> {
private final ClassInfo info;
- LazyClassLoaderRef(ClassInfo info) { + LazyClassLoaderRef(ReferenceBundle bundle, ClassInfo info) { + super(bundle); this.info = info; }
@@ -395,7 +405,7 @@ } }
- private static class DebugRef extends FinalizableRef.DebugRef<Class> { + private static class DebugRef extends ManagedReference<Class> { public final static boolean debug = false;
private static final AtomicInteger count = new AtomicInteger(); @@ -403,14 +413,14 @@ final String name;
public DebugRef(Class klazz) { - super(klazz); + super(softBundle, klazz); name = klazz == null ? "<null>" : klazz.getName(); count.incrementAndGet(); }
public void finalizeRef() {
System.out.println(name + " unloaded " + count.decrementAndGet() +
" classes kept");
- super.finalizeRef();
+ super.finalizeReference();
}
}
}
Index: main/org/codehaus/groovy/reflection/CachedClass.java
===================================================================
--- main/org/codehaus/groovy/reflection/CachedClass.java (Revision 13791)
+++ main/org/codehaus/groovy/reflection/CachedClass.java (Arbeitskopie)
@@ -18,10 +18,13 @@
import groovy.lang.*;
import org.codehaus.groovy.classgen.BytecodeHelper;
import org.codehaus.groovy.runtime.callsite.CallSiteClassLoader;
-import org.codehaus.groovy.util.LazySoftReference;
import org.codehaus.groovy.util.LazyReference;
import org.codehaus.groovy.util.FastArray;
+import org.codehaus.groovy.util.ReferenceManager;
+import org.codehaus.groovy.util.ReferenceType;
+import org.codehaus.groovy.util.ManagedReference.ReferenceBundle;
+import java.lang.ref.ReferenceQueue;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -36,8 +39,16 @@
public class CachedClass {
private final Class cachedClass;
public ClassInfo classInfo;
+
+ private static ReferenceBundle softBundle;
+ static {
+ ReferenceQueue queue = new ReferenceQueue();
+ ReferenceManager callBack =
ReferenceManager.createCallBackedManager(queue);
+ ReferenceManager manager =
ReferenceManager.createThresholdedIdlingManager(queue, callBack, 500);
+ softBundle = new ReferenceBundle(manager, ReferenceType.SOFT);
+ }
- private final LazySoftReference<CachedField[]> fields = new
LazySoftReference<CachedField[]>() {
+ private final LazyReference<CachedField[]> fields = new
LazyReference<CachedField[]>(softBundle) {
public CachedField[] initValue() {
final Field[] declaredFields = (Field[])
AccessController.doPrivileged(new
PrivilegedAction/*<Field[]>*/() {
@@ -54,7 +65,7 @@
}
};
- private LazySoftReference<CachedConstructor[]> constructors = new
LazySoftReference<CachedConstructor[]>() {
+ private LazyReference<CachedConstructor[]> constructors = new
LazyReference<CachedConstructor[]>(softBundle) {
public CachedConstructor[] initValue() {
final Constructor[] declaredConstructors = (Constructor[])
AccessController.doPrivileged(new
PrivilegedAction/*<Constructor[]>*/() {
@@ -69,7 +80,7 @@
}
};
- private LazySoftReference<CachedMethod[]> methods = new
LazySoftReference<CachedMethod[]>() {
+ private LazyReference<CachedMethod[]> methods = new
LazyReference<CachedMethod[]>(softBundle) {
public CachedMethod[] initValue() {
final Method[] declaredMethods = (Method[])
AccessController.doPrivileged(new
PrivilegedAction/*<Method[]>*/() {
@@ -114,7 +125,8 @@
}
};
- private LazyReference<CachedClass> cachedSuperClass = new
LazyReference<CachedClass>() {
+ /* nicht SOFT xxx */
+ private LazyReference<CachedClass> cachedSuperClass = new
LazyReference<CachedClass>(softBundle) {
public CachedClass initValue() {
if (!isArray)
return
ReflectionCache.getCachedClass(getTheClass().getSuperclass());
@@ -126,7 +138,7 @@
}
};
- private final LazySoftReference<CallSiteClassLoader> callSiteClassLoader =
new LazySoftReference<CallSiteClassLoader>() {
+ private final LazyReference<CallSiteClassLoader> callSiteClassLoader = new
LazyReference<CallSiteClassLoader>(softBundle) {
public CallSiteClassLoader initValue() {
return
AccessController.doPrivileged(new
PrivilegedAction<CallSiteClassLoader>() {
@@ -144,7 +156,8 @@
public CachedMethod [] mopMethods;
public static final CachedClass[] EMPTY_ARRAY = new CachedClass[0];
- private final LazyReference<Set<CachedClass>> declaredInterfaces = new
LazyReference<Set<CachedClass>> () {
+ /* nicht SOFT xxx */
+ private final LazyReference<Set<CachedClass>> declaredInterfaces = new
LazyReference<Set<CachedClass>> (softBundle) {
public Set<CachedClass> initValue() {
HashSet<CachedClass> res = new HashSet<CachedClass> (0);
@@ -156,7 +169,7 @@ } };
- private final LazySoftReference<Set<CachedClass>> interfaces = new
LazySoftReference<Set<CachedClass>> () {
+ private final LazyReference<Set<CachedClass>> interfaces = new
LazyReference<Set<CachedClass>> (softBundle) {
public Set<CachedClass> initValue() {
HashSet<CachedClass> res = new HashSet<CachedClass> (0);
Index: main/org/codehaus/groovy/util/AbstractConcurrentMapBase.java
===================================================================
--- main/org/codehaus/groovy/util/AbstractConcurrentMapBase.java (Revision
13791)
+++ main/org/codehaus/groovy/util/AbstractConcurrentMapBase.java (Arbeitskopie)
@@ -8,7 +8,7 @@
final int segmentShift;
protected final Segment[] segments;
- public AbstractConcurrentMapBase() { + public AbstractConcurrentMapBase(Object segmentInfo) { int sshift = 0; int ssize = 1; while (ssize < 16) { @@ -27,10 +27,10 @@ cap <<= 1;
for (int i = 0; i < this.segments.length; ++i) - this.segments[i] = createSegment(cap); + this.segments[i] = createSegment(segmentInfo, cap); }
- protected abstract Segment createSegment(int cap); + protected abstract Segment createSegment(Object segmentInfo, int cap);
protected static <K> int hash(K key) {
int h = System.identityHashCode(key);
Index: main/org/codehaus/groovy/util/ReferenceType.java
===================================================================
--- main/org/codehaus/groovy/util/ReferenceType.java (Revision 0)
+++ main/org/codehaus/groovy/util/ReferenceType.java (Revision 0)
@@ -0,0 +1,93 @@
+package org.codehaus.groovy.util;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+
+
+public enum ReferenceType {
+ SOFT {
+ @Override
+ protected <T,V extends Finalizable> Reference<T,V> createReference(T
value, V handler, ReferenceQueue queue) {
+ return new SoftRef(value, handler, queue);
+ }
+ },
+ WEAK {
+ @Override
+ protected <T,V extends Finalizable> Reference<T,V> createReference(T
value, V handler, ReferenceQueue queue) {
+ return new WeakRef(value, handler, queue);
+ }
+ },
+ PHANTOM {
+ @Override
+ protected <T,V extends Finalizable> Reference<T,V> createReference(T
value, V handler, ReferenceQueue queue) {
+ return new PhantomRef(value, handler, queue);
+ }
+ },
+ HARD {
+ @Override
+ protected <T,V extends Finalizable> Reference<T,V> createReference(T
value, V handler, ReferenceQueue queue) {
+ return new HardRef(value, handler, queue);
+ }
+ };
+ protected abstract <T,V extends Finalizable> Reference<T,V>
createReference(T value, V handler, ReferenceQueue queue);
+
+ private static class SoftRef<TT,V extends Finalizable> extends
SoftReference<TT> implements Reference<TT,V> {
+ private final V handler;
+ public SoftRef(TT referent, V handler, ReferenceQueue<? super TT> q) {
+ super(referent, q);
+ this.handler = handler;
+ }
+ @Override
+ public V getHandler() {
+ return handler;
+ }
+ }
+
+ private static class WeakRef<TT,V extends Finalizable> extends
WeakReference<TT> implements Reference<TT,V> {
+ private final V handler;
+ public WeakRef(TT referent, V handler, ReferenceQueue<? super TT> q) {
+ super(referent, q);
+ this.handler = handler;
+ }
+ @Override
+ public V getHandler() {
+ return handler;
+ }
+ }
+
+ private static class PhantomRef<TT,V extends Finalizable> extends
PhantomReference<TT> implements Reference<TT,V> {
+ private final V handler;
+ public PhantomRef(TT referent, V handler, ReferenceQueue<? super TT> q)
{
+ super(referent, q);
+ this.handler = handler;
+ }
+ @Override
+ public V getHandler() {
+ return handler;
+ }
+ }
+
+ private static class HardRef<TT,V extends Finalizable> implements
Reference<TT,V> {
+ private TT ref;
+ private final V handler;
+ public HardRef(TT referent, V handler, ReferenceQueue<? super TT> q) {
+ this.ref = referent;
+ this.handler = handler;
+ }
+ @Override
+ public V getHandler() {
+ return handler;
+ }
+ @Override
+ public TT get() {
+ return ref;
+ }
+ @Override
+ public void clear() {
+ ref = null;
+ }
+ }
+
+}
Index: main/org/codehaus/groovy/util/AbstractConcurrentMap.java
===================================================================
--- main/org/codehaus/groovy/util/AbstractConcurrentMap.java (Revision 13791)
+++ main/org/codehaus/groovy/util/AbstractConcurrentMap.java (Arbeitskopie)
@@ -1,7 +1,9 @@
package org.codehaus.groovy.util;
public abstract class AbstractConcurrentMap<K, V> extends
AbstractConcurrentMapBase {
- public AbstractConcurrentMap() {
+
+ public AbstractConcurrentMap(Object segmentInfo) {
+ super(segmentInfo);
}
public Segment segmentFor (int hash) {
Index: main/org/codehaus/groovy/util/AbstractConcurrentDoubleKeyMap.java
===================================================================
--- main/org/codehaus/groovy/util/AbstractConcurrentDoubleKeyMap.java (Revision
13791)
+++ main/org/codehaus/groovy/util/AbstractConcurrentDoubleKeyMap.java
(Arbeitskopie)
@@ -1,7 +1,8 @@
package org.codehaus.groovy.util;
public abstract class AbstractConcurrentDoubleKeyMap<K1,K2,V> extends
AbstractConcurrentMapBase {
- public AbstractConcurrentDoubleKeyMap() {
+ public AbstractConcurrentDoubleKeyMap(Object segmentInfo) {
+ super(segmentInfo);
}
static <K1,K2> int hash(K1 key1, K2 key2) { Index: main/org/codehaus/groovy/util/ManagedReference.java =================================================================== --- main/org/codehaus/groovy/util/ManagedReference.java (Revision 13791) +++ main/org/codehaus/groovy/util/ManagedReference.java (Arbeitskopie) @@ -1,127 +1,52 @@ package org.codehaus.groovy.util;
-import java.lang.ref.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.Set;
-import java.util.LinkedHashSet;
-
-public interface FinalizableRef {
-
- public void finalizeRef ();
-
- public static abstract class SoftRef<T> extends SoftReference<T> implements
FinalizableRef {
- public SoftRef(T referent) {
- super(referent, MyReferenceQueue.getInstance());
+/**
+ *
+ *
+ * @author Alex Tkachman
+ * @author Jochen Theodorou
+ */
+public class ManagedReference<T> implements Finalizable {
+ public static class ReferenceBundle{
+ private ReferenceManager manager;
+ private ReferenceType type;
+ public ReferenceBundle(ReferenceManager manager, ReferenceType type){
+ this.manager = manager;
+ this.type = type;
}
-
- public String toString() {
- T res = get ();
- if (res == null)
- return "<null>";
- else
- return res.toString();
+ public ReferenceType getType() {
+ return type;
}
-
- public void finalizeRef () {
- }
+ public ReferenceManager getManager() {
+ return manager;
+ }
}
-
- public static abstract class WeakRef<T> extends WeakReference<T> implements
FinalizableRef {
- public WeakRef(T referent) {
- super(referent, MyReferenceQueue.getInstance());
- }
-
- public String toString() {
- T res = get ();
- if (res == null)
- return "<null>";
- else
- return res.toString();
- }
-
- public void finalizeRef () {
- }
+
+ private static ReferenceManager NULL_MANAGER = new
ReferenceManager(null){};
+ private Reference<T,ManagedReference<T>> ref;
+ private ReferenceManager manager;
+
+ public ManagedReference(ReferenceType type, ReferenceManager rmanager, T
value) {
+ if (rmanager==null) rmanager = NULL_MANAGER;
+ this.manager = rmanager;
+ this.ref = type.createReference(value, this,
rmanager.getReferenceQueue());
+ rmanager.afterReferenceCreation(ref);
}
-
- public static abstract class PhantomRef<T> extends PhantomReference<T>
implements FinalizableRef {
- public PhantomRef(T referent) {
- super(referent, MyReferenceQueue.getInstance());
- }
-
- public void finalizeRef () {
- }
+
+ public ManagedReference(ReferenceBundle bundle, T value) {
+ this(bundle.getType(),bundle.getManager(),value);
}
-
- /**
- * Phantom reference, which will be kept alive while not finalized.
- * There is no need to store this references anywhere because they will be
automatically put in to internal set.
- * Subclasses should overide finalizeRef () method and call
super.finalizeRef () to do any additional cleanup or dyagnostic
- */
- public static abstract class DebugRef<T> extends PhantomRef<T> {
- private static final ConcurrentHashMap<FinalizableRef,Object> anchor =
new ConcurrentHashMap<FinalizableRef,Object> ();
- private static final Object ANCHOR = new Object();
-
- public DebugRef(T referent) {
- super(referent);
- anchor.put(this, ANCHOR);
- }
-
- public void finalizeRef () {
- super.clear();
- anchor.remove(this);
- }
+
+ public final T get() {
+ return ref.get();
}
-
- public static class MyReferenceQueue extends ReferenceQueue {
- private static final MyReferenceQueue finalizableQueue = new
MyReferenceQueue();
-
- private AtomicInteger refCnt = new AtomicInteger();
-
- private AtomicReference<Thread> thread = new AtomicReference<Thread>
();
-
- public MyReferenceQueue() {
- }
-
- private ReferenceQueue getMe () {
- if (thread.get() == null) {
- final Thread newThread = new MyThread();
- if (thread.compareAndSet(null, newThread)) {
- newThread.setContextClassLoader(null);
- newThread.setDaemon(true);
- newThread.setName(FinalizableRef.class.getName());
- newThread.start();
- }
- }
-
- refCnt.incrementAndGet();
- return this;
- }
-
- public static ReferenceQueue getInstance() {
- return finalizableQueue.getMe ();
- }
-
- private class MyThread extends Thread {
- public void run() {
- while (true) {
- try {
- FinalizableRef ref = (FinalizableRef) remove(5000);
- if (ref == null) {
- if (refCnt.get() == 0) {
- thread.compareAndSet(this, null);
- return;
- }
- } else {
- refCnt.decrementAndGet();
- ref.finalizeRef();
- }
- }
- catch (Throwable t) {//
- }
- }
- }
- }
+
+ public final void clear() {
+ ref.clear();
+ manager.removeStallEntries();
}
-}
+
+ public void finalizeReference(){
+ clear();
+ }
+}
\ No newline at end of file
Eigenschaftsänderungen: main/org/codehaus/groovy/util/ManagedReference.java
___________________________________________________________________ Hinzugefügt: svn:mergeinfo
Index: main/org/codehaus/groovy/util/ConcurrentSoftMap.java
===================================================================
--- main/org/codehaus/groovy/util/ConcurrentSoftMap.java (Revision 13791)
+++ main/org/codehaus/groovy/util/ConcurrentSoftMap.java (Arbeitskopie)
@@ -1,78 +0,0 @@
-package org.codehaus.groovy.util;
-
-public class ConcurrentSoftMap<K,V> extends AbstractConcurrentMap<K,V> {
- public ConcurrentSoftMap() {
- }
-
- protected Segment<K,V> createSegment(int cap) {
- return new ConcurrentSoftMap.Segment<K,V>(cap);
- }
-
- public static class Segment<K,V> extends
AbstractConcurrentMap.Segment<K,V>{
- public Segment(int cap) {
- super(cap);
- }
-
- protected AbstractConcurrentMap.Entry<K,V> createEntry(K key, int hash,
V value) {
- return new EntryWithValue<K,V>(this, key, hash, value);
- }
- }
-
- public static class Entry<K,V> extends FinalizableRef.SoftRef<K> implements
AbstractConcurrentMap.Entry<K,V> {
- private final Segment segment;
- private int hash;
-
- public Entry(Segment segment, K key, int hash) {
- super(key);
- this.segment = segment;
- this.hash = hash;
- }
-
- public boolean isValid() {
- return get() != null;
- }
-
- public boolean isEqual(K key, int hash) {
- return this.hash == hash && get() == key;
- }
-
- public V getValue() {
- return (V)this;
- }
-
- public void setValue(V value) {
- }
-
- public int getHash() {
- return hash;
- }
-
- public void finalizeRef() {
- super.finalizeRef();
- segment.removeEntry(this);
- }
- }
-
- public static class EntryWithValue<K,V> extends Entry<K,V> {
- private V value;
-
- public EntryWithValue(Segment segment, K key, int hash, V value) {
- super(segment, key, hash);
- setValue(value);
- }
-
- public V getValue() {
- return value;
- }
-
- public void setValue(V value) {
- this.value = value;
- }
-
-
- public void finalizeRef() {
- value = null;
- super.finalizeRef();
- }
- }
-}
\ No newline at end of file
Index: main/org/codehaus/groovy/util/FinalizableRef.java
===================================================================
--- main/org/codehaus/groovy/util/FinalizableRef.java (Revision 13791)
+++ main/org/codehaus/groovy/util/FinalizableRef.java (Arbeitskopie)
@@ -1,127 +0,0 @@
-package org.codehaus.groovy.util;
-
-import java.lang.ref.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.Set;
-import java.util.LinkedHashSet;
-
-public interface FinalizableRef {
-
- public void finalizeRef ();
-
- public static abstract class SoftRef<T> extends SoftReference<T> implements
FinalizableRef {
- public SoftRef(T referent) {
- super(referent, MyReferenceQueue.getInstance());
- }
-
- public String toString() {
- T res = get ();
- if (res == null)
- return "<null>";
- else
- return res.toString();
- }
-
- public void finalizeRef () {
- }
- }
-
- public static abstract class WeakRef<T> extends WeakReference<T> implements
FinalizableRef {
- public WeakRef(T referent) {
- super(referent, MyReferenceQueue.getInstance());
- }
-
- public String toString() {
- T res = get ();
- if (res == null)
- return "<null>";
- else
- return res.toString();
- }
-
- public void finalizeRef () {
- }
- }
-
- public static abstract class PhantomRef<T> extends PhantomReference<T>
implements FinalizableRef {
- public PhantomRef(T referent) {
- super(referent, MyReferenceQueue.getInstance());
- }
-
- public void finalizeRef () {
- }
- }
-
- /**
- * Phantom reference, which will be kept alive while not finalized.
- * There is no need to store this references anywhere because they will be
automatically put in to internal set.
- * Subclasses should overide finalizeRef () method and call
super.finalizeRef () to do any additional cleanup or dyagnostic
- */
- public static abstract class DebugRef<T> extends PhantomRef<T> {
- private static final ConcurrentHashMap<FinalizableRef,Object> anchor =
new ConcurrentHashMap<FinalizableRef,Object> ();
- private static final Object ANCHOR = new Object();
-
- public DebugRef(T referent) {
- super(referent);
- anchor.put(this, ANCHOR);
- }
-
- public void finalizeRef () {
- super.clear();
- anchor.remove(this);
- }
- }
-
- public static class MyReferenceQueue extends ReferenceQueue {
- private static final MyReferenceQueue finalizableQueue = new
MyReferenceQueue();
-
- private AtomicInteger refCnt = new AtomicInteger();
-
- private AtomicReference<Thread> thread = new AtomicReference<Thread>
();
-
- public MyReferenceQueue() {
- }
-
- private ReferenceQueue getMe () {
- if (thread.get() == null) {
- final Thread newThread = new MyThread();
- if (thread.compareAndSet(null, newThread)) {
- newThread.setContextClassLoader(null);
- newThread.setDaemon(true);
- newThread.setName(FinalizableRef.class.getName());
- newThread.start();
- }
- }
-
- refCnt.incrementAndGet();
- return this;
- }
-
- public static ReferenceQueue getInstance() {
- return finalizableQueue.getMe ();
- }
-
- private class MyThread extends Thread {
- public void run() {
- while (true) {
- try {
- FinalizableRef ref = (FinalizableRef) remove(5000);
- if (ref == null) {
- if (refCnt.get() == 0) {
- thread.compareAndSet(this, null);
- return;
- }
- } else {
- refCnt.decrementAndGet();
- ref.finalizeRef();
- }
- }
- catch (Throwable t) {//
- }
- }
- }
- }
- }
-}
Index: main/org/codehaus/groovy/util/SoftDoubleKeyMap.java
===================================================================
--- main/org/codehaus/groovy/util/SoftDoubleKeyMap.java (Revision 13791)
+++ main/org/codehaus/groovy/util/SoftDoubleKeyMap.java (Arbeitskopie)
@@ -1,108 +0,0 @@
-/*
- * Copyright 2003-2007 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.codehaus.groovy.util;
-
-public class SoftDoubleKeyMap<K1,K2,V> extends
AbstractConcurrentDoubleKeyMap<K1,K2,V> {
- protected AbstractConcurrentDoubleKeyMap.Segment<K1,K2,V> createSegment(int
cap) {
- return new Segment<K1,K2,V>(cap);
- }
-
- static class Segment<K1,K2,V> extends
AbstractConcurrentDoubleKeyMap.Segment<K1,K2,V>{
- public Segment(int cap) {
- super(cap);
- }
-
- protected AbstractConcurrentDoubleKeyMap.Entry<K1,K2,V> createEntry(K1
key1, K2 key2, int hash) {
- return new EntryWithValue(key1, key2, hash, this);
- }
- }
-
- static class Ref<K> extends FinalizableRef.SoftRef<K> {
- final Entry entry;
- public Ref(K referent, Entry entry) {
- super(referent);
- this.entry = entry;
- }
-
- public void finalizeRef() {
- this.entry.clean();
- }
-
- public void clear() {
- super.clear();
- }
- }
-
- public static class Entry<K1,K2, V> implements
AbstractConcurrentDoubleKeyMap.Entry<K1,K2,V> {
- final private int hash;
- final Ref<K1> ref1;
- final Ref<K2> ref2;
- final Segment segment;
-
- public Entry(K1 key1, K2 key2, int hash, Segment segment) {
- this.hash = hash;
- this.segment = segment;
- ref1 = new Ref(key1, this);
- ref2 = new Ref(key2, this);
- }
-
- public boolean isValid() {
- return ref1.get() != null && ref2.get () != null;
- }
-
- public boolean isEqual(K1 key1, K2 key2, int hash) {
- return this.hash == hash && ref1.get() == key1 && ref2.get() ==
key2;
- }
-
- public V getValue() {
- return (V)this;
- }
-
- public void setValue(V value) {
- }
-
- public int getHash() {
- return hash;
- }
-
- public void clean() {
- segment.removeEntry(this);
- ref1.clear();
- ref2.clear();
- }
- }
-
- private static class EntryWithValue<K1,K2,V> extends Entry<K1,K2,V> {
- private V value;
-
- public EntryWithValue(K1 key1, K2 key2, int hash, Segment segment) {
- super(key1, key2, hash, segment);
- }
-
- public V getValue() {
- return value;
- }
-
- public void setValue(V value) {
- this.value = value;
- }
-
- public void clean() {
- super.clean();
- value = null;
- }
- }
-}
Index: main/org/codehaus/groovy/util/Finalizable.java
===================================================================
--- main/org/codehaus/groovy/util/Finalizable.java (Revision 0)
+++ main/org/codehaus/groovy/util/Finalizable.java (Revision 0)
@@ -0,0 +1,5 @@
+package org.codehaus.groovy.util;
+
+public interface Finalizable {
+ public void finalizeReference();
+}
Index: main/org/codehaus/groovy/util/ConcurrentWeakMap.java
===================================================================
--- main/org/codehaus/groovy/util/ConcurrentWeakMap.java (Revision 13791)
+++ main/org/codehaus/groovy/util/ConcurrentWeakMap.java (Arbeitskopie)
@@ -1,78 +0,0 @@
-package org.codehaus.groovy.util;
-
-public class ConcurrentWeakMap<K,V> extends AbstractConcurrentMap<K,V> {
- public ConcurrentWeakMap() {
- }
-
- protected Segment<K,V> createSegment(int cap) {
- return new ConcurrentWeakMap.Segment<K,V>(this, cap);
- }
-
- public static class Segment<K,V> extends
AbstractConcurrentMap.Segment<K,V>{
- public Segment(ConcurrentWeakMap<K,V> map, int cap) {
- super(cap);
- }
-
- protected AbstractConcurrentMap.Entry<K,V> createEntry(K key, int hash,
V value) {
- return new EntryWithValue<K,V>(this, key, hash, value);
- }
- }
-
- public static class Entry<K,V> extends FinalizableRef.WeakRef<K> implements
AbstractConcurrentMap.Entry<K,V> {
- private final Segment segment;
- private int hash;
-
- public Entry(Segment segment, K key, int hash) {
- super(key);
- this.segment = segment;
- this.hash = hash;
- }
-
- public boolean isValid() {
- return get() != null;
- }
-
- public boolean isEqual(K key, int hash) {
- return this.hash == hash && get() == key;
- }
-
- public V getValue() {
- return (V)this;
- }
-
- public void setValue(V value) {
- }
-
- public int getHash() {
- return hash;
- }
-
- public void finalizeRef() {
- super.finalizeRef();
- segment.removeEntry(this);
- }
- }
-
- public static class EntryWithValue<K,V> extends Entry<K,V> {
- private V value;
-
- public EntryWithValue(Segment segment, K key, int hash, V value) {
- super(segment, key, hash);
- setValue(value);
- }
-
- public V getValue() {
- return value;
- }
-
- public void setValue(V value) {
- this.value = value;
- }
-
-
- public void finalizeRef() {
- value = null;
- super.finalizeRef();
- }
- }
-}
\ No newline at end of file
Index: main/org/codehaus/groovy/util/ReferenceManager.java
===================================================================
--- main/org/codehaus/groovy/util/ReferenceManager.java (Revision 0)
+++ main/org/codehaus/groovy/util/ReferenceManager.java (Revision 0)
@@ -0,0 +1,132 @@
+package org.codehaus.groovy.util;
+
+import java.lang.ref.ReferenceQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class ReferenceManager {
+ private static class ThreadedReferenceManager extends ReferenceManager {
+ private final Thread thread;
+ private volatile boolean shouldRun = true;
+ public ThreadedReferenceManager(ReferenceQueue queue) {
+ super(queue);
+ thread = new Thread() {
+ public void run() {
+ ReferenceQueue queue = getReferenceQueue();
+ java.lang.ref.Reference r=null;
+ while (shouldRun) {
+ try {
+ r = queue.remove(1000);
+ } catch (InterruptedException e) {
+ break;
+ }
+ if (r==null) continue;
+
+ if (r instanceof Reference) {
+ Reference ref = (Reference) r;
+ Finalizable holder = ref.getHandler();
+ if (holder!=null) holder.finalizeReference();
+ }
+ r.clear();
+ r=null;
+ }
+ }
+ };
+ thread.setContextClassLoader(null);
+ thread.setDaemon(true);
+ thread.setName(ThreadedReferenceManager.class.getName());
+ thread.start();
+ }
+ @Override
+ public void stopThread() {
+ shouldRun = false;
+ thread.interrupt();
+ }
+ @Override
+ public String toString() {
+ return "ReferenceManager(threaded, thread="+thread+")";
+ }
+ }
+
+ public static ReferenceManager createThreadedManager(ReferenceQueue queue)
{
+ return new ThreadedReferenceManager(queue);
+ }
+ public static ReferenceManager createIdlingManager(ReferenceQueue queue) {
+ return new ReferenceManager(queue);
+ }
+ public static ReferenceManager createCallBackedManager(ReferenceQueue
queue) {
+ return new ReferenceManager(queue){
+ @Override
+ public void removeStallEntries() {
+ ReferenceQueue queue = getReferenceQueue();
+ for(;;) {
+ java.lang.ref.Reference r = queue.poll();
+ if (r==null) break;
+
+ if (r instanceof Reference) {
+ Reference ref = (Reference) r;
+ Finalizable holder = ref.getHandler();
+ if (holder!=null) holder.finalizeReference();
+ }
+ r.clear();
+ r=null;
+ }
+ }
+ @Override
+ public void afterReferenceCreation(Reference r) {
+ removeStallEntries();
+ }
+ @Override
+ public String toString() {
+ return "ReferenceManager(callback)";
+ }
+ };
+ }
+ public static ReferenceManager createThresholdedIdlingManager(final
ReferenceQueue queue, final ReferenceManager callback, final int threshold) {
+ if (threshold<0) throw new IllegalArgumentException("threshold must not
be below 0.");
+
+ return new ReferenceManager(queue){
+ private AtomicInteger refCnt = new AtomicInteger();
+ private volatile ReferenceManager manager =
createIdlingManager(queue);
+ @Override
+ public void afterReferenceCreation(Reference r) {
+ if (manager==callback) {
+ callback.afterReferenceCreation(r);
+ return;
+ }
+ // we use the idle manager, so let us use the reference counter
+ // we change the manager once the threshold is reached. There
is
+ // a small chance that the value will go beyond
Integer.MAX_VALUe
+ // so we check for values below 0 too. If threshold is low,
then
+ // this is unlikely to happen. If threshold is high, then we
+ // have all negative values as fall back
+ int count = refCnt.incrementAndGet();
+ if (count>threshold || count<0) {
+ manager = callback;
+ }
+ }
+ @Override
+ public String toString() {
+ return "ReferenceManager(thresholded, current
manager="+manager+", threshold="+refCnt.get()+"/"+threshold+")";
+ }
+ };
+ }
+
+ private ReferenceQueue queue;
+
+ public ReferenceManager(ReferenceQueue queue) {
+ this.queue = queue;
+ }
+
+ protected ReferenceQueue getReferenceQueue() {
+ return queue;
+ }
+
+ public void afterReferenceCreation(Reference r) {}
+ public void removeStallEntries() {}
+ public void stopThread() {}
+
+ @Override
+ public String toString() {
+ return "ReferenceManager(idling)";
+ }
+}
Index: main/org/codehaus/groovy/util/LazySoftReference.java
===================================================================
--- main/org/codehaus/groovy/util/LazySoftReference.java (Revision 13791)
+++ main/org/codehaus/groovy/util/LazySoftReference.java (Arbeitskopie)
@@ -1,76 +0,0 @@
-package org.codehaus.groovy.util;
-
-import java.lang.ref.SoftReference;
-
-/**
- * Soft reference with lazy initialization under lock
- */
-public abstract class LazySoftReference<T> extends LockableObject {
- private SoftReference<T> value;
-
- public T get() {
- SoftReference<T> resRef = value;
- T res;
- if (resRef != null && (res = resRef.get()) != null)
- return res;
-
- return getLocked();
- }
-
- private T getLocked () {
- lock ();
- try {
- SoftReference<T> resRef = value;
- T res;
- if (resRef != null && (res = resRef.get()) != null)
- return res;
-
- res = initValue();
- value = new MySoftRef<T>(res);
- return res;
- }
- finally {
- unlock();
- }
- }
-
- public void set (T newVal) {
- if (newVal == null)
- value = null;
- else
- value = new MySoftRef<T>(newVal);
- }
-
- public T getNullable() {
- SoftReference<T> resRef = value;
- T res;
- if (resRef == null || (res = resRef.get()) == null) {
- return null;
- }
- return res;
- }
-
- public abstract T initValue();
-
- protected void finalizeRef() {
- value = null;
- }
-
- public String toString() {
- T res = getNullable();
- if (res == null)
- return "<null>";
- else
- return res.toString();
- }
-
- private class MySoftRef<T> extends FinalizableRef.SoftRef<T> {
- public MySoftRef(T res) {
- super(res);
- }
-
- public void finalizeRef() {
- LazySoftReference.this.finalizeRef();
- }
- }
-}
Index: main/org/codehaus/groovy/util/ManagedConcurrentMap.java
===================================================================
--- main/org/codehaus/groovy/util/ManagedConcurrentMap.java (Revision 13791)
+++ main/org/codehaus/groovy/util/ManagedConcurrentMap.java (Arbeitskopie)
@@ -1,29 +1,42 @@
package org.codehaus.groovy.util;
-public class ConcurrentWeakMap<K,V> extends AbstractConcurrentMap<K,V> {
- public ConcurrentWeakMap() {
+import org.codehaus.groovy.util.ManagedReference.ReferenceBundle;
+
+public class ManagedConcurrentMap<K,V> extends AbstractConcurrentMap<K,V> {
+ protected ReferenceBundle bundle;
+ public ManagedConcurrentMap(ReferenceBundle bundle) {
+ super(bundle);
+ this.bundle = bundle;
+ if (bundle==null) throw new IllegalArgumentException("bundle must not
be null");
}
- protected Segment<K,V> createSegment(int cap) {
- return new ConcurrentWeakMap.Segment<K,V>(this, cap);
+ protected Segment<K,V> createSegment(Object segmentInfo, int cap) {
+ ReferenceBundle bundle = (ReferenceBundle) segmentInfo;
+ if (bundle==null) throw new IllegalArgumentException("bundle must not
be null");
+ return new ManagedConcurrentMap.Segment<K,V>(bundle, cap);
}
public static class Segment<K,V> extends
AbstractConcurrentMap.Segment<K,V>{
- public Segment(ConcurrentWeakMap<K,V> map, int cap) {
+ protected final ReferenceBundle bundle;
+ public Segment(ReferenceBundle bundle, int cap) {
super(cap);
+ this.bundle = bundle;
+ if (bundle==null) throw new IllegalArgumentException("bundle must
not be null");
+
}
protected AbstractConcurrentMap.Entry<K,V> createEntry(K key, int hash,
V value) {
- return new EntryWithValue<K,V>(this, key, hash, value);
+ if (bundle==null) throw new IllegalArgumentException("bundle must
not be null");
+ return new EntryWithValue<K,V>(bundle, this, key, hash, value);
}
}
- public static class Entry<K,V> extends FinalizableRef.WeakRef<K> implements
AbstractConcurrentMap.Entry<K,V> {
+ public static class Entry<K,V> extends ManagedReference<K> implements
AbstractConcurrentMap.Entry<K,V> {
private final Segment segment;
private int hash;
- public Entry(Segment segment, K key, int hash) {
- super(key);
+ public Entry(ReferenceBundle bundle, Segment segment, K key, int hash)
{
+ super(bundle, key);
this.segment = segment;
this.hash = hash;
}
@@ -48,7 +61,7 @@
}
public void finalizeRef() { - super.finalizeRef(); + super.finalizeReference(); segment.removeEntry(this); } } @@ -56,8 +69,8 @@ public static class EntryWithValue<K,V> extends Entry<K,V> { private V value;
- public EntryWithValue(Segment segment, K key, int hash, V value) {
- super(segment, key, hash);
+ public EntryWithValue(ReferenceBundle bundle, Segment segment, K key,
int hash, V value) {
+ super(bundle, segment, key, hash);
setValue(value);
}
Eigenschaftsänderungen: main/org/codehaus/groovy/util/ManagedConcurrentMap.java
___________________________________________________________________ Hinzugefügt: svn:mergeinfo
Index: main/org/codehaus/groovy/util/ManagedDoubleKeyMap.java =================================================================== --- main/org/codehaus/groovy/util/ManagedDoubleKeyMap.java (Revision 13791) +++ main/org/codehaus/groovy/util/ManagedDoubleKeyMap.java (Arbeitskopie) @@ -15,35 +15,40 @@ */ package org.codehaus.groovy.util;
-public class SoftDoubleKeyMap<K1,K2,V> extends
AbstractConcurrentDoubleKeyMap<K1,K2,V> {
- protected AbstractConcurrentDoubleKeyMap.Segment<K1,K2,V> createSegment(int
cap) {
- return new Segment<K1,K2,V>(cap);
+import org.codehaus.groovy.util.ManagedReference.ReferenceBundle;
+
+public class ManagedDoubleKeyMap<K1,K2,V> extends
AbstractConcurrentDoubleKeyMap<K1,K2,V> {
+ public ManagedDoubleKeyMap(ReferenceBundle bundle) {
+ super(bundle);
}
+
+ protected AbstractConcurrentDoubleKeyMap.Segment<K1,K2,V>
createSegment(Object segmentInfo, int cap) {
+ ReferenceBundle bundle = (ReferenceBundle) segmentInfo;
+ return new Segment<K1,K2,V>(bundle, cap);
+ }
static class Segment<K1,K2,V> extends
AbstractConcurrentDoubleKeyMap.Segment<K1,K2,V>{
- public Segment(int cap) {
+ private ReferenceBundle bundle;
+ public Segment(ReferenceBundle bundle, int cap) {
super(cap);
+ this.bundle = bundle;
}
protected AbstractConcurrentDoubleKeyMap.Entry<K1,K2,V> createEntry(K1
key1, K2 key2, int hash) {
- return new EntryWithValue(key1, key2, hash, this);
+ return new EntryWithValue(bundle, key1, key2, hash, this);
}
}
- static class Ref<K> extends FinalizableRef.SoftRef<K> { + static class Ref<K> extends ManagedReference<K> { final Entry entry; - public Ref(K referent, Entry entry) { - super(referent); + public Ref(ReferenceBundle bundle, K referent, Entry entry) { + super(bundle, referent); this.entry = entry; }
public void finalizeRef() { this.entry.clean(); } - - public void clear() { - super.clear(); - } }
public static class Entry<K1,K2, V> implements
AbstractConcurrentDoubleKeyMap.Entry<K1,K2,V> {
@@ -52,11 +57,11 @@
final Ref<K2> ref2;
final Segment segment;
- public Entry(K1 key1, K2 key2, int hash, Segment segment) {
+ public Entry(ReferenceBundle bundle, K1 key1, K2 key2, int hash,
Segment segment) {
this.hash = hash;
this.segment = segment;
- ref1 = new Ref(key1, this);
- ref2 = new Ref(key2, this);
+ ref1 = new Ref(bundle, key1, this);
+ ref2 = new Ref(bundle, key2, this);
}
public boolean isValid() { @@ -88,8 +93,8 @@ private static class EntryWithValue<K1,K2,V> extends Entry<K1,K2,V> { private V value;
- public EntryWithValue(K1 key1, K2 key2, int hash, Segment segment) {
- super(key1, key2, hash, segment);
+ public EntryWithValue(ReferenceBundle bundle, K1 key1, K2 key2, int
hash, Segment segment) {
+ super(bundle, key1, key2, hash, segment);
}
public V getValue() {
Eigenschaftsänderungen: main/org/codehaus/groovy/util/ManagedDoubleKeyMap.java
___________________________________________________________________ Hinzugefügt: svn:mergeinfo
Index: main/org/codehaus/groovy/util/LazyReference.java =================================================================== --- main/org/codehaus/groovy/util/LazyReference.java (Revision 13791) +++ main/org/codehaus/groovy/util/LazyReference.java (Arbeitskopie) @@ -1,76 +1,59 @@ package org.codehaus.groovy.util;
-import java.lang.ref.SoftReference; +import org.codehaus.groovy.util.ManagedReference.ReferenceBundle;
+
/**
* Soft reference with lazy initialization under lock
*/
-public abstract class LazySoftReference<T> extends LockableObject {
- private SoftReference<T> value;
-
+public abstract class LazyReference<T> extends LockableObject {
+ private final static ManagedReference INIT = new
ManagedReference(ReferenceType.HARD,null,null){};
+ private final static ManagedReference NULL_REFERENCE = new
ManagedReference(ReferenceType.HARD,null,null){};
+ private ManagedReference<T> reference = INIT;
+ private final ReferenceBundle bundle;
+
+ public LazyReference(ReferenceBundle bundle) {
+ this.bundle = bundle;
+ }
+
public T get() {
- SoftReference<T> resRef = value;
- T res;
- if (resRef != null && (res = resRef.get()) != null)
- return res;
-
- return getLocked();
+ ManagedReference<T> resRef = reference;
+ if (resRef == INIT) return getLocked(false);
+ if (resRef == NULL_REFERENCE) return null;
+ T res = resRef.get();
+ // res== null means it got collected
+ if (res==null) return getLocked(true);
+ return res;
}
- private T getLocked () { + private T getLocked (boolean force) { lock (); try { - SoftReference<T> resRef = value; - T res; - if (resRef != null && (res = resRef.get()) != null) - return res; - - res = initValue(); - value = new MySoftRef<T>(res); + ManagedReference<T> resRef = reference; + if (!force && resRef != INIT) return resRef.get(); + T res = initValue(); + if (res == null) { + reference = NULL_REFERENCE; + } else { + reference = new ManagedReference<T>(bundle,res); + } return res; - } - finally { + } finally { unlock(); } }
- public void set (T newVal) { - if (newVal == null) - value = null; - else - value = new MySoftRef<T>(newVal); + public void clear() { + reference = INIT; }
- public T getNullable() { - SoftReference<T> resRef = value; - T res; - if (resRef == null || (res = resRef.get()) == null) { - return null; - } - return res; - } - public abstract T initValue();
- protected void finalizeRef() { - value = null; - } - public String toString() { - T res = getNullable(); + T res = reference.get(); if (res == null) return "<null>"; else return res.toString(); } - - private class MySoftRef<T> extends FinalizableRef.SoftRef<T> { - public MySoftRef(T res) { - super(res); - } - - public void finalizeRef() { - LazySoftReference.this.finalizeRef(); - } - } }
Eigenschaftsänderungen: main/org/codehaus/groovy/util/LazyReference.java
___________________________________________________________________ Hinzugefügt: svn:mergeinfo
Index: main/org/codehaus/groovy/util/Reference.java =================================================================== --- main/org/codehaus/groovy/util/Reference.java (Revision 0) +++ main/org/codehaus/groovy/util/Reference.java (Revision 0) @@ -0,0 +1,7 @@ +package org.codehaus.groovy.util; + +public interface Reference<T,V extends Finalizable> { + T get(); + void clear(); + V getHandler(); +}
--------------------------------------------------------------------- To unsubscribe from this list, please visit:








.zip