[vtkusers] problems with java memory management
Sebastien Jourdain
sebastien.jourdain at kitware.com
Wed Nov 24 16:24:10 EST 2010
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