Ian Rogers wrote:
> Anyway, this design decision seems to hang off how weak references are
> finalized. If they are finalized on their own finalizer thread then the
> final local index design is fine and preferable imo to the volatile
> design or a weak identity hash map (however cached or stream lined) - I
> think an indexed register load is the shortest bit of code you could
> produce for this. If finalizable objects are finalized as part of
> tearing down threads then a leak is possible and for correctness the
> volatile should be used. So this comes down to a question of how
> Classpath using VMs are finalizing objects?
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
Regards,
Jeroen