Jeroen Frijters wrote:
No, any VM that implements the spec is vulnerable. Here's an example of a possible attack:class Attacker { static ArrayList<ThreadLocal> resurrected; ArrayList<ThreadLocal> list = new ArrayList<ThreadLocal>(); Attacker() { for (int i = 0; i < 1000; i++) { list.add(new ThreadLocal()); } } protected void finalize() { resurrected = list; } static void attack() { new Attacker(); System.gc(); System.runFinalization(); runSomeHighTrustCodeThatWillAllocateThreadLocal(); for (ThreadLocal t : resurrected) { if (t.get() != null) { System.out.println("We've stolen the object:" + t.get()); } } } } I hope this clarifies the problem with finalizers. A PhantomReference doesn't suffer from this problem, because it only gets enqueued after the object *really* is gone. For another example of this bug in GNU Classpath see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29499
Thanks Jeroen, it's clear now. The problem with a phantom reference is that when we collect the thread local we should also really make collectable all of the values set to thread locals. A phantom reference won't do this and so introduces a memory leak until something can run over the queue of phantom references freeing all the allocated thread local slots. As you say, we can use phantom references, wouldn't another way be to implement say our own system weak reference, with a guarantee there are no references and weak references to the object? Having a thread that polls a normally empty queue seems undesirable both for this and Classpath bug 29499.
Thanks again, Ian
