[vtkusers] VTK/Java crashes -- WeakGlobalRef or garbage collection problem...solution?

Luke Dodd luke.dodd at gmail.com
Mon Dec 21 12:28:07 EST 2009


I'm not sure either method is as good as we could manage.

A problem that applies to both methods is that they each require the
use of finalize for every object to be cleaned up.

My solution is not so neat because of the ugly global lock (although
I'm not sure this would slow things down measurably compared  to
general wrapping overheads). Another problem with my method us that
there is still access, albeit not concurrent to native vtk objects
from multiple threads. As I understand access from multiple threads
can be a problem for opengl, but I can't see how a call to Delete
would lead to opengl calls from the same thread, could someone explain
(perhaps clearing up vertex buffers or something)?

Nathan's solution is nice and flexable. The problem I have is with the
default implementation dumping lot's of Runnables onto the Event queue
every time garbage collection is run, this seems like it might not be
such a good idea when many objects need to be cleaned up (pehaps the
cost of this is not so high, some test cases should help figure this
out). Of course this can be fixed by tweaking what the default
behaviour is, and the user can ultimately control this.

I have another idea for a solution that would not rely on finalizers
and could have good flexibility. As I typed this out I realised its
pretty complex and only worth considering if finalizers are indeed
_that_ bad (as mentioned in Clinton's link -
http://publib.boulder.ibm.com/infocenter/javasdk/v6r0/index.jsp?topic=/com.ibm.java.doc.diagnostics.60/html/mm_gc_coexist.html
) . The idea is to periodically step through vtkGlobalJavaHash key
value pairs looking for any value that has been set null. If it has
been set to null this means that garbage collection has cleaned up any
strong references to the object, therefore has to null the weak
references. Then we could use the key for said value to call Delete on
the vtk object (this stage might actually have a fair amount of
overhead). It would be easy enough to make vtkObject finaziers
increment some counter/timer so occasionally it would cause a sweep
through vtkGlobalJavaHash on whatever thread we wanted (or choose some
other way to prompt cleanup). I think this method is only useful if
finalizers and multi-threaded access are really "bad" - but I thought
I'd mention it.

I think I'll throw together some test cases, and try both methods in
the git repo before speculating any more.

If anyone has contributions about how bad/good multi-threaded access
and relying on finalizers is I'd like to hear!

Whichever method is chosen I think it'll be great to finally have some
stable java wrappers in CVS :-)

Thanks,
Luke


> The proxyFinalize solution looks more elegant to me. So if I
> understand correctly, you can write your own class that implements
> vtkIDisposeOnThread, and call the static method setDisposer() to
> change what happens in Java's finalize(). Is it true that you would
> only want to change the disposer once at program startup? Perhaps that
> should be clear in the documentation if so.
>
> After we get a fix for this in CVS, it would be good to also commit
> one or two tests that test extreme gc behavior to make sure this stays
> fixed in the future.
>
> I'll plan on committing proxyFinalize early next year if there aren't
> serious objections. Until then, if you are a Java VTK developer,
> please exercise this solution so we can make tweaks before it goes in.
>
> Jeff
>



More information about the vtkusers mailing list