Fwd: [vtkusers] VTK/Java crashes -- WeakGlobalRef or garbage collection problem?

Jeff Lee jeff at cdnorthamerica.com
Tue Jun 19 09:22:48 EDT 2007


---------- Forwarded message ----------
From: Jeff Lee <jeff.lee at us.cd-adapco.com>
Date: Jun 19, 2007 9:13 AM
Subject: Re: [vtkusers] VTK/Java crashes -- WeakGlobalRef or garbage
collection problem?
To: Eran Guendelman <erang at stanford.edu>
Cc: vtkusers at vtk.org

If you want the method-scope ref to be valid across jni calls, NewGlobalRef
is the one to use, but the java-side object won't be gc'ed even if it is
eligible, unless DeleteGlobalRef is called.  WeakGlobalRef is supposed to be
the solution to that, but with the caveat that the ref could be yanked away
from you when the gc runs.  In vtk java wrapping, the c++ objects allocated
in java aren't deleted until the java object is gc'ed (in the objects
finalizer).  To get DeleteGlobalRef called from java without relying on
garbage collection would require a specific call to something like
obj.VTKDelete(), which is not at all what you would like to do in java.
This can all be avoided by altering your programming style a bit by not
grabbing references to vtk member objects with method-only scope.  This
might look like

public void setNormalAtLocation(vtkDataArray array, int index, double x,
double y, double z) {
         array.SetTuple3(index, x, y, z);
}

to get the normals array, try caching the pointData as an ivar somewhere
when you set the vtkPolyData, then it is a matter of
pointData.GetArray("XXX"), or pointData.GetNormals().  If you have your own
java object which hasa or isa vtkDataSet, then that is probably the right
place to do the caching.  not the prettiest solution, but it keeps the
garbage collector from yanking your temporary reference.
-Jeff

On 6/18/07, Eran Guendelman <erang at stanford.edu > wrote:
>
> We're getting very weird crashes using VTK with Java wrappings.  They're
>   weird because they occur at random times during the execution of our
> program, but when run long enough they always do seem to eventually
> occur (e.g. after 2-5 minutes).  My main approach to getting it to crash
>   is to start the animation in our application, the animation makes lots
> of calls to functions such as these
>
> public void setNormalAtLocation(int index, double x, double y, double z) {
>
>         vtkPointData t = pointPolyData.GetPointData();
>          vtkDataArray u = t.GetNormals();
>          u.SetTuple3(index, x, y, z);
> }
>
> and
>
> public void setTensorDataAtLocation(int index, double xx, double xy,
> double xz, double yx, double yy, double yz, double zx, double zy, double
> zz)
> {
>          vtkPointData t = pointPolyData.GetPointData();
>          t.GetTensors().SetTuple9(index, xx, xy, xz, yx, yy, yz, zx, zy,
> zz);
> }
>
> and the crash typically occurs inside one of these functions.
> pointPolyData is a class member of type vtkPolyData.
> methods exist.
>
> I've #defined VTKJAVADEBUG when compiling the (debug) VTK libraries, and
> also added other print statements for my own debugging use, and by
> examining the output I've started to see a pattern in what seems to be
> causing the crash.  Basically, there are two threads that are calling
> down to VTK C++ calls... these are the main event thread, and the
> finalizer thread which does garbage collection.  What seems to be
> happening is that in a call such as
>
>         vtkPointData t = pointPolyData.GetPointData ();
>          vtkDataArray u = t.GetNormals();
>
> when the GetNormals is getting processed in the C++ side, for some
> reason the garbage collector seems to think that t can be deallocated,
> and the finalizer deletes it from under the feet of the main event
> thread which expects it to exist... so e.g. we have something like
>
> t.GetNormals()
>         causes the execution of
> Java_vtk_vtkDataSetAttributes_GetNormals_120
>         which calls
> vtkJavaGetPointerFromObject
>         which calls vtkJavaGetId and gets a valid id for the object, but
> then
> gets ptr = 0 and command = 0 for that object because in the meantime the
> garbage collector has called vtkJavaDeleteObject which deleted it from
> the hash table
>
>         So now back in
> Java_vtk_vtkDataSetAttributes_GetNormals_120
>         it receives a NULL pointer, but assumes it's not NULL and calls
> (op)->GetNormals()
>         causing a crash!
>
> Anyway, in vtkJavaUtil.cxx I found that weak global references were used
> (NewWeakGlobalRef and DeleteWeakGlobalRef called, at least for
> JNI_VERSION_1_2 and up which is the case in our install).  Admittedly I
> don't know much about these creatures, but looking online I found a
> comment in http://java.sun.com/j2se/1.4.2/docs/guide/jni/jni-12.html
> saying that weak global references are dangerous because they don't
> count as a real reference as far as garbage collection is concerned, and
> the type of potential problem mentioned in this document sounded very
> similar to what we are experiencing (objects getting garbage collected
> during call to native method).  So I tried changing to non-weak global
> refs (NewGlobalRef and DeleteGlobalRef), and indeed found that our
> crashes seemed to stop (by which I mean I ran it for 10 minutes without
> crashing which never happened before...  doesn't conclusively mean the
> crash is fixed, but seems to be a positive change).
>
>
> So has anyone else experienced a similar problem?  Anyone know whether
> the use of weak global references by VTK/Java is indeed a mistake, or
> should they be working and we just have some other problem with our code?
>
> Any help would be greatly appreciated,
>
> Eran.
>
>
> _______________________________________________
> This is the private VTK discussion list.
> Please keep messages on-topic. Check the FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20070619/64463234/attachment.htm>


More information about the vtkusers mailing list