Memory leak with circular TTree

Hi all,

I’m using TTree to do online histogram generation in a DAQ environment. The relevant bits of code are:

void SpectrumMaker::Initialize(){
  _hist = new TH1D("_hist","Live Histogram", 200,0,1000);
  _tree = new TTree((GetName()+"tree").c_str(),"");
  _tree->SetCircular(1);
  _tree->SetDirectory(0);
  EventData* ptr = new EventData;
  _branch = _tree->Branch(EventData::GetBranchName(),&ptr);
  _branch->SetAddress(0);
  delete ptr;
}

void SpectrumMaker::Process(EventData* evt){
  _branch->SetAddress( &ptr );
  _tree->Fill();
  _tree->Draw("channels[0].intgral >>+_hist", "","goff");
}

When I run this, my memory grows quickly until the program explodes. I can make and delete instances of the EventData class fine, so I’m fairly sure the problem is not there. In fact if I just take out the “Draw” line, everything is OK, so even the filling with the circular buffer seems to work just fine.

I’ve tried calling various Reset functions on the branch and the tree, but nothing seems to work. Any suggestions?

Looking at some old forum posts, I see some have had issues with STL vectors. If it’s relevant, the EventData class contains a vector of ChannelData objects, which themselves contain vectors of RegionOfInterest and Pulse objects. (The class is defined here: bloer.github.io/daqman/doc/html/ … ource.html).

Many thanks,
~Ben

Draw() will cumulate the points in the current canvas. And even if your tree is circular TList in the canvas will grow. At least thats how I interpret this phenomena.

I can try checking the canvas’s TList easily enough. But I’m that this should be the case, since (a) I’m using the “goff” Draw option and (b) using the “>>+hist” notation; based on the documentation, it seems like that should just be filling the histogram, and since the histogram bins are already allocated, should not use more memory.
EDIT: The canvas list of entries is not growing in size, so this seems not to be the problem.

Ok … It was just a guess. As you said that the Draw() directive was the faulty one I thought it might be the explanation. So in must be in the Draw() machinery but in the TTree part … not in the graphics one.

Digging through some valgrind dumps now. One problem looks to be at line 3291 of TTreeFormula.cxx:

if (cl) {
      if (cl->GetClassInfo()) {
         if (cl->GetMethodAllAny(method)) {
            // Let's try to see if the function we found belongs to the current
            // class.  Note that this implementation currently can not work if
            // one the argument is another leaf or data member of the object.
            // (Anyway we do NOT support this case).
            TMethodCall* methodcall = new TMethodCall(cl, method, params);
            if (methodcall->GetMethod()) {
               // We have a method that works.
               // We will use it.
               return kTRUE;
            }
            delete methodcall;
         }
      }
   }

   return kFALSE;

If the method is found the function returns before deleting the new pointer.

EDIT: Fixing that leak seems to have done it; I guess this should be submitted as a bug report. I’m using 5.34p19, but it looks like it’s still present in the head version.

On a side note, it would appear the method I’m using is repeatedly calling on the interpreter (viat TTreeFormula::Compile) to parse the actual Draw string (which I suppose shouldn’t surprise me.) Given that this is the same command every event, is there any trick I can use to avoid re-parsing every time?

Hi all,

I think I’m having the same problem as reported here. I’m using the TTree::Draw method to generate histograms on a large loop, and at some point the system kills the process because of memory consumption. Using valgrind I also found out that it is caused by the aforementioned method and the TTreeFormula class. Obviously if I comment the lines related with the TTree::Draw method the problem disappears. I’m using root 6.04.02. Does exist any plan to solve it?

I did file a bug report 1.5 years ago (!) which has not seen any action: sft.its.cern.ch/jira/browse/ROOT-6923

Seems an awfully long time for a bug with a 3 line fix. I don’t see any way to promote the bug or anything though.

Solved here now:
root.cern.ch/gitweb?p=root.git; … 745d2b429c