[vtkusers] problems with java memory management

Sebastien Jourdain sebastien.jourdain at kitware.com
Wed Nov 24 16:53:30 EST 2010


Thanks,

I'm happy that I was able to help you.

Seb

On Wed, Nov 24, 2010 at 4:45 PM, Mark Roden <mmroden at gmail.com> wrote:
>
> - return stripper.GetOutput(); // Maybe it is OK but I'm not sure...
>
> This looks like it's just a dangerous line altogether.  Removing it seems to
> have brought the leak down to about ~10-~40 mb per instance, which could
> just be noise since I can't directly profile things.
>
> Thanks much for the help!
> Mark
>
> On Wed, Nov 24, 2010 at 1:24 PM, Sebastien Jourdain
> <sebastien.jourdain at kitware.com> wrote:
>>
>> This is OK
>> - renWin.GetRenderer().AddActor(outlineActor);
>> - for (int j=0; j<cell.GetNumberOfPoints()-1; j++)
>>
>> This is NOT OK
>> - stripper.SetInput(marching.GetOutput());
>> - return stripper.GetOutput(); // Maybe it is OK but I'm not sure...
>>
>> Accessing a value is ok but asking a vtkObject to give a reference to
>> one of its internal to another vtkObject is not OK if you don't
>> provide a temporary Java object inbetween.
>>
>> Seb
>>
>> On Wed, Nov 24, 2010 at 4:14 PM, Mark Roden <mmroden at gmail.com> wrote:
>> > Hi Sebastien,
>> >
>> > I've made the changes, as in:
>> >
>> >
>> >         vtkPolyData marchingoutput = marching.GetOutput();
>> >
>> >         stripper.SetInput(marchingoutput);
>> >
>> > instead of
>> >
>> > stripper.SetInput(marching.GetOutput());
>> >
>> > But in order for this to be effective, do I need to correct lines like
>> >
>> >         renWin.GetRenderer().AddActor(outlineActor);
>> >
>> > Should that be split, or can I continue to have multiple command stacked
>> > like that?  Could the renWin.GetRenderer() leak in the above line?
>> >
>> > How about a method that returns something like
>> >
>> >         return stripper.GetOutput();
>> >
>> > Will that leak?
>> >
>> > or
>> >
>> >             for (int j=0; j<cell.GetNumberOfPoints()-1; j++)
>> >
>> > I have a lot of inlining (if that's the proper term in this context) in
>> > my
>> > code.  If the only way to solve this problem is to have each individual
>> > vtk
>> > call be its own call, that's a pretty big refactor.  So are there
>> > certain
>> > rules I can use to avoid this? If it's just making sure that one output
>> > doesn't directly go into another input, that's straightforward.  Buf it
>> > it's
>> > 'every time a function with .get' is called, then I need to fix quite a
>> > bit
>> > more.
>> >
>> > This approach does look like it's pulled the leak down somewhat, but not
>> > entirely.
>> >
>> > Mark
>> >
>> >
>> >
>> > On Wed, Nov 24, 2010 at 12:56 PM, Sebastien Jourdain
>> > <sebastien.jourdain at kitware.com> wrote:
>> >>
>> >> Hi Mark,
>> >>
>> >> I agree it is a common habit in Java. But this problem ONLY if object
>> >> is a vtkObject. If it's one of your Java object, this is not a
>> >> problem.
>> >>
>> >> Seb
>> >>
>> >> On Wed, Nov 24, 2010 at 3:11 PM, Mark Roden <mmroden at gmail.com> wrote:
>> >> > Hi Sebastian,
>> >> >
>> >> > Thanks for giving me a place to start.  I'll take a look at my
>> >> > various
>> >> > pipelines and see where/if I'm doing things like that.  I probably
>> >> > am,
>> >> > since
>> >> > that kind of line saving is just what I'd do.
>> >> >
>> >> > I'll let you and the list know.
>> >> >
>> >> > Mark
>> >> >
>> >> > On Wed, Nov 24, 2010 at 9:37 AM, Sebastien Jourdain
>> >> > <sebastien.jourdain at kitware.com> wrote:
>> >> >>
>> >> >> Hi Mark,
>> >> >>
>> >> >> it might be related to the way you bind vtk object together. I mean
>> >> >> by
>> >> >> bind something like the following expression.
>> >> >>
>> >> >> actor.SetMapper( object.GetMapper() );
>> >> >>
>> >> >> In fact VTK can have some issue with reference count if you provide
>> >> >> a
>> >> >> VTK object reference across the C++ layer without going through the
>> >> >> Java object layer. (Sorry it is not very clear, but it is quite
>> >> >> difficult to explain.)
>> >> >>
>> >> >> So to solve this problem, you should rewrite the above expression
>> >> >> like
>> >> >> that.
>> >> >>
>> >> >> vtkDataSetMapper mapper = object.GetMapper();
>> >> >> actor.SetMapper( mapper );
>> >> >>
>> >> >> Hope that helped and please let us know if that solved your problem.
>> >> >>
>> >> >> Seb
>> >> >>
>> >> >>
>> >> >> On Tue, Nov 23, 2010 at 11:15 PM, Mark Roden <mmroden at gmail.com>
>> >> >> wrote:
>> >> >> > Hi all,
>> >> >> >
>> >> >> > I'm having problems with memory management in java (windows 7, 64
>> >> >> > bit
>> >> >> > and 32
>> >> >> > bit, vtk 5.6).
>> >> >> >
>> >> >> > The application loads ~150mb of dicom images (varies from patient
>> >> >> > to
>> >> >> > patient), allocates between 1 to 10 binary masks on top of those
>> >> >> > images,
>> >> >> > and
>> >> >> > then Does Things, things that include PolyData contours.
>> >> >> >
>> >> >> > Once I'm done with an image, I want to completely wipe all
>> >> >> > instances
>> >> >> > of
>> >> >> > vtk
>> >> >> > and start afresh with a new image.
>> >> >> >
>> >> >> > So, I'm calling
>> >> >> >
>> >> >> > vtkGlobalJavaHash.GC();
>> >> >> >
>> >> >> > But that doesn't work, even after I delete all windows and data
>> >> >> > holders.
>> >> >> >
>> >> >> > So, I go ahead and get more aggressive, calling
>> >> >> >
>> >> >> > vtkGlobalJavaHash.DeleteAll();
>> >> >> >
>> >> >> > This call works somewhat better, but appears to leave ~150 mb
>> >> >> > behind
>> >> >> > (coincidentally, the size of the original image).  When I use the
>> >> >> > netbeans
>> >> >> > memory profiler at this point, I get no indication that this
>> >> >> > memory
>> >> >> > is
>> >> >> > actually in use; I'm seeing the memory allocations via the system
>> >> >> > resources
>> >> >> > in the task manager.
>> >> >> >
>> >> >> > I then try something a bit more drastic:
>> >> >> >
>> >> >> >     private int DeleteAllVTKObjects(){
>> >> >> >         int deleted = 0;
>> >> >> >         Set entries =
>> >> >> > vtkGlobalJavaHash.PointerToReference.entrySet();
>> >> >> >         Iterator iter = entries.iterator();
>> >> >> >         while (iter.hasNext()) {
>> >> >> >             Map.Entry entry = (Map.Entry) iter.next();
>> >> >> >             vtkObjectBase obj = (vtkObjectBase) ((WeakReference)
>> >> >> > entry.getValue()).get();
>> >> >> >             if (obj == null) {
>> >> >> >                 // Delete a garbage collected object using the raw
>> >> >> > C++
>> >> >> > pointer.
>> >> >> >                 long id = ((Long)entry.getKey()).longValue();
>> >> >> >                 vtkObjectBase.VTKDeleteReference(id);
>> >> >> >                 entries.remove(entry);
>> >> >> >                 deleted++;
>> >> >> >             }
>> >> >> >             else if (obj != null){
>> >> >> >                 // Delete a non-garbage collected object.
>> >> >> >                 // We use Delete() which will call the "real" C++
>> >> >> > Delete()
>> >> >> >                 // unless Delete() has been called on this Java
>> >> >> > object
>> >> >> > before.
>> >> >> >                 // Delete() will remove from the map so we don't
>> >> >> > have
>> >> >> > to.
>> >> >> >                 obj.Delete();
>> >> >> >                 deleted++;
>> >> >> >             }
>> >> >> >         }
>> >> >> >         return deleted;
>> >> >> >     }
>> >> >> >
>> >> >> > But that appears to be the same (or no better than)
>> >> >> > vtkGlobalJavaHash.DeleteAll().
>> >> >> >
>> >> >> > So here's the deal: I've got ~140 mb leaking with each image that
>> >> >> > I
>> >> >> > open,
>> >> >> > and the profiler indicates that the leak is not in Java.
>> >> >> >
>> >> >> > I'm using the vtkGDCMImageReader to read in images, and this
>> >> >> > object
>> >> >> > does
>> >> >> > not
>> >> >> > (as far as I can see) have a dispose method.  I'm using
>> >> >> > vtkPolyData
>> >> >> > objects,
>> >> >> > but again, I'm not seeing dispose methods.  I'm using
>> >> >> > vtkGDCMPolyDataReader
>> >> >> > and to handle contours, again, no dispose method present.
>> >> >> >
>> >> >> > So right now, I'm thinking that either those particular classes
>> >> >> > have
>> >> >> > leaks
>> >> >> > on the C++ side, or some memory is just not getting handled and
>> >> >> > removed
>> >> >> > by
>> >> >> > the above calls to vtk.
>> >> >> >
>> >> >> > Are there other ways I can debug this issue?  I want the user to
>> >> >> > be
>> >> >> > able
>> >> >> > to
>> >> >> > open and close as many images as they want, rather than having to
>> >> >> > restart
>> >> >> > the program every ~10 or so images due to instabilities from the
>> >> >> > leak.
>> >> >> >
>> >> >> > Also, due to problems I mentioned previously on the list with
>> >> >> > changes
>> >> >> > in
>> >> >> > the
>> >> >> > vtk libraries, I can't move to the head version of vtk.  If the
>> >> >> > head
>> >> >> > version
>> >> >> > has a fix, I can try it, but right now, gdcm and vtk head do not
>> >> >> > play
>> >> >> > well
>> >> >> > together at all.  It seems that the vtkStringArrays necessary to
>> >> >> > read
>> >> >> > in
>> >> >> > files on the gdcm side are empty when passed through the java
>> >> >> > layer
>> >> >> > in
>> >> >> > 5.7,
>> >> >> > but not in 5.6 (which I discovered through that error << trick
>> >> >> > from
>> >> >> > Monday,
>> >> >> > thanks for that).  I don't know why that is, but since 5.6 works
>> >> >> > with
>> >> >> > gdcm
>> >> >> > git head, that's the version I have.
>> >> >> >
>> >> >> > Thanks,
>> >> >> > Mark
>> >> >> >
>> >> >> > _______________________________________________
>> >> >> > Powered by www.kitware.com
>> >> >> >
>> >> >> > Visit other Kitware open-source projects at
>> >> >> > http://www.kitware.com/opensource/opensource.html
>> >> >> >
>> >> >> > Please keep messages on-topic and check the VTK FAQ at:
>> >> >> > http://www.vtk.org/Wiki/VTK_FAQ
>> >> >> >
>> >> >> > Follow this link to subscribe/unsubscribe:
>> >> >> > http://www.vtk.org/mailman/listinfo/vtkusers
>> >> >> >
>> >> >> >
>> >> >
>> >> >
>> >
>> >
>
>



More information about the vtkusers mailing list