I started getting StackOverflow exceptions today around clojure.lang.Keyword (I'm running clojure 1.2.0, but the code doesn't seem to be different in github master).
It looks like intern is keeping a ConcurrentHashMap of SoftReference objects. The problem is that when the SoftReference exists, but the payload of the SoftReference (the thing you get from .get()) is null, it tries to call intern again: public static Keyword intern(Symbol sym){ Util.clearCache(rq, table); Keyword k = new Keyword(sym); SoftReference<Keyword> existingRef = table.putIfAbsent(sym, new SoftReference<Keyword>(k,rq)); if(existingRef == null) return k; Keyword existingk = existingRef.get(); if(existingk != null) return existingk; //entry died in the interim, do over return intern(sym); } It's counting on Util.clearCache and a ReferenceQueue at rq to clear out objects that have been GC'd, but the documentation for SoftReferences says: "Suppose that the garbage collector determines at a certain point in time that an object is softly reachable. At that time it may choose to clear atomically all soft references to that object and all soft references to any other softly-reachable objects from which that object is reachable through a chain of strong references. At the same time or at some later time it will enqueue those newly-cleared soft references that are registered with reference queues." This means to me that it is non-deterministic when the VM will enqueue the reference into the ReferenceQueue, you just know that it will happen at some point in time. I'm assuming that my code was in a state where the Keyword got GC'd, but that hadn't been enqueued in the ReferenceQueue yet and thus the SoftReference wasn't cleared out of the Map and it recursed until it got a StackOverflow. I think a simple fix for this could be to do a "table.remove(sym, existingRef)" right before the "return intern(sym);". This would ensure that the recursive call will succeed and since Util.clearCache is doing the same call, shouldn't have any adverse side-effects. --Eric -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en