summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2010-06-30 15:05:23 -0400
committerRich Hickey <richhickey@gmail.com>2010-06-30 15:05:23 -0400
commit0f4b6495347dc7d9601cc0907d5d08dd861bb3aa (patch)
tree219f86d561ff228f61d086bc1d7c9397cbd58522
parent04764db9b213687dd5d4325c67291f0b0ef3ff33 (diff)
clean out dead entries in dynamic class cache
-rw-r--r--src/jvm/clojure/lang/DynamicClassLoader.java40
1 files changed, 22 insertions, 18 deletions
diff --git a/src/jvm/clojure/lang/DynamicClassLoader.java b/src/jvm/clojure/lang/DynamicClassLoader.java
index 3f3ab35e..d27e9c86 100644
--- a/src/jvm/clojure/lang/DynamicClassLoader.java
+++ b/src/jvm/clojure/lang/DynamicClassLoader.java
@@ -19,14 +19,17 @@ import java.util.concurrent.ConcurrentHashMap;
import java.net.URLClassLoader;
import java.net.URL;
import java.lang.ref.WeakReference;
+import java.lang.ref.ReferenceQueue;
public class DynamicClassLoader extends URLClassLoader{
HashMap<Integer, Object[]> constantVals = new HashMap<Integer, Object[]>();
-static ConcurrentHashMap<String, Map.Entry<WeakReference<Class>,Object> >classCache =
- new ConcurrentHashMap<String, Map.Entry<WeakReference<Class>,Object> >();
+static ConcurrentHashMap<String, WeakReference<Class> >classCache =
+ new ConcurrentHashMap<String, WeakReference<Class> >();
static final URL[] EMPTY_URLS = new URL[]{};
+static final ReferenceQueue rq = new ReferenceQueue();
+
public DynamicClassLoader(){
//pseudo test in lieu of hasContextClassLoader()
super(EMPTY_URLS,(Thread.currentThread().getContextClassLoader() == null ||
@@ -39,29 +42,30 @@ public DynamicClassLoader(ClassLoader parent){
}
public Class defineClass(String name, byte[] bytes, Object srcForm){
-// Map.Entry<WeakReference<Class>,Object> ce = classCache.get(name);
-// if(ce != null)
-// {
-// WeakReference<Class> cr = ce.getKey();
-// Class c = cr.get();
-// if((c != null) && srcForm.equals(ce.getValue()))
-// return c;
-// }
Class c = defineClass(name, bytes, 0, bytes.length);
- classCache.put(name, new MapEntry(new WeakReference(c), null));
+ classCache.put(name, new WeakReference(c,rq));
+ //cleanup any dead entries
+ if(rq.poll() != null)
+ {
+ while(rq.poll() != null)
+ ;
+ for(Map.Entry<String,WeakReference<Class>> e : classCache.entrySet())
+ {
+ if(e.getValue().get() == null)
+ classCache.remove(e.getKey(), e.getValue());
+ }
+ }
return c;
}
protected Class<?> findClass(String name) throws ClassNotFoundException{
- Map.Entry<WeakReference<Class>,Object> ce = classCache.get(name);
- if(ce != null)
- {
- WeakReference<Class> cr = ce.getKey();
- Class c = cr.get();
+ WeakReference<Class> cr = classCache.get(name);
+ if(cr != null)
+ {
+ Class c = cr.get();
if(c != null)
return c;
- classCache.remove(name);
- }
+ }
return super.findClass(name);
}