PyROOT and libNew - trying to find memory leaks

Dear Rooters,

root-config --version --svn-revision --python-version 5.19/01 21745 2.5

I’m trying to track down a memory leak in my PyROOT app, and I was wanting to know if there is an obvious way to try and find memory leaks.

I tried valgrind, but that was pretty useless - there was an awful lot of errors from all over the place in both python and ROOT. (even with python.supp and root.supp). Suggestions on how I might find my problems specific to my code with valgrind are welcome.

I am having a very strange problem where apparently “delete” within a C++ module (called from python) does not seem to be functioning. I have a loop with a few thousand iterations and I seem to be allocating ~7mb each iteration. I’m almost certain (but obviously not, because there is a problem somewhere) that I am deleting everything, yet my memory usage (gSystem->GetProcInfo(i), i.fMemResident) keeps climbing. Should I expect this quantity to go down when I delete things?

Is there any way I can override new/delete (Within C++) with my own allocator that does some book-keeping?

Are there any other resources, both python or C++ that will help me with finding memory problems?

Regards,

  • Peter

Peter,

care to post (a snippet of) the problematic code? E.g., are you passing the objects to C++ through a non-const pointer? Are there circular references?

There are two settings that PyROOT can operate under: heuristics and strict. The former works very well with ROOT code, but some people really don’t like it. :slight_smile: See here: http://cern.ch/wlav/pyroot/memory.html (and also in the ROOT manual, PyROOT chapter).

For instrumenting one’s own classes, here is one idea: http://cern.ch/wlav/ctotw/ctotw11.html.

As for other tools, I like memprof: http://www.gnome.org/projects/memprof/, because it allows the user to make snap-shots during the run, rather than waiting until the end of the program.

Cheers,
Wim

This is really awesome wlav. Great, thanks for your help.

If I find what is causing the problem, I will post it here.

Regards,

  • Peter

I built up a script which tracks object creation and destruction through ROOT’s TClass:GetInstanceCount mechanism (attached). Using this I was able to see that objects coming from ROOT side (such as those created from a histogram Projection), were quickly mounting up, and needed to be deleted python side.

I was using object.Delete() thinking that it would remove objects - and it worked for most objects, except for some lists I had. List overrides Delete() to mean ‘Delete objects within the collection’, which meant the list itself was not being deleted.

This command is handy:

object.IsA().Destructor( object )

The link you gave me was very useful.

Finally, is there any way to give python ownership of an object that originated on the ROOT side, then have the object follow normal python GC behavior?

Regards, and thanks for your help fixing this.

Peter,

on the same page:o = ROOT.TObject() ROOT.SetOwnership( o, False ) # True to own, False to release
So in your case, use ‘True’. I still want to update that to do this on a per function basis. I.e. that all objects returned by a so designated function are owned by python. Haven’t gotten around to it yet, though.
For now, you can wrap the function with a decorator.

Cheers,
Wim

1 Like

Ah, sorry, my bad, I missed it and confused SetOwnership with SetMemoryPolicy.

Thanks for your help.