[vtkusers] VTK/Java crashes -- WeakGlobalRef or garbage collection problem...solution?
Luke Dodd
luke.dodd at gmail.com
Mon Dec 21 12:56:01 EST 2009
I've just been doing some more thinking...
If people have written Java code that does not use swing (for example
just standard vtk windows) then delegating Deletes to the swing thread
is not going to fix anything (since the original problems was Deletes
happening concurrently with other vtk code). Is everyone using vtk
Java wrappers doing so from a swing application, from the swing event
thread? We'll need to document somewhere exactly where it's being done
and what users need to do to avoid problems.
Furthermore if an application is non-interactive (constantly
processing, not waiting for user input) then it would be tricky to
have an event-queue in the code. One would have to override the depose
proxy with a custom event/clean-up queue and periodically call to
process it, or risk running out of memory in some cases.This puts a
fairly heavy burden on the user, for some simply requiring a manual
call to Delete might be easier to understand.
My first patch avoids this without any additional effort from the
user, but could cause random "pauses" on the processing thread during
finalization dud to the locks. (any existing code out there would be
fine, although I'm not sure how much of that there is)
What do people think?
I'm happy to clean my original patch up, or try to implement
other/hybrid methods that show promise.
Thanks,
Luke
2009/12/21 Luke Dodd <luke.dodd at gmail.com>:
> 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