In the following example, I just open a root file, write down a dummy
histogram and close it. I avoid any dynamical allocation.
THF1 and TFile are declared in a subfunction of the main program (and not
as static), they are consequently local and have a lifetime related to the
execution of the function.
Nevertheless, the allocated memory gets larger as I reexecute the
function (if I have well understood how TStorage works).
By looking closely at the created root classes, I see that some classes
remain on the heap, mainly originating from the histogram..., but also
from the TFile.
I have removed them by hand, but it doesn't even really help.
So is it a bug (from me?) or a feature ? In both cases, how to
properly clean the memory ?
The source file should be compiled with a standart Makefile
I use version 220 of Root.
Thanks,
best regard,
David Gourio
========================================================================
Mail : GSI, Abteilung KP3 D-64291 Darmstadt
E-Mail : D.Gourio@gsi.de
Phone : +49 6159 71 27 79
Fax : +49 6159 71 29 89
------------------------------Source---------------------------------
#include <iostream.h>
#include <TROOT.h>
#include <TUnixSystem.h>
#include <TH1.h>
#include <TFile.h>
char * PrintBool(Bool_t MyBoolean) {
if (MyBoolean) return "True";
else return "False";
}
void ProcessFile(char * RootFileName) {
TUnixSystem Lili;
TFile RH_File;
// Dummy histogram to be written in the root file
TH1F DummyHisto("Dummy", "I am empty", 100, 0., 1.);
// Open the file, take care if it already exists
if (Lili.AccessPathName(RootFileName) ) {
// File does not exist yet.
RH_File.Open(RootFileName,"CREATE","Gros appetit");
}
else {
// File already exists
RH_File.Open(RootFileName,"UPDATE");
}
// Write down in the file the dummy histogram, overwrite instead of
// creating a new version of the object
DummyHisto.Write(DummyHisto.GetName(), TObject::kOverwrite);
RH_File.Close();
}
int main() {
TROOT MyRoot("xx", "xx xx");
// For checking the objects still in memory...
TObject * obj;
TIter * AllClassesList;
// Root file name
char * RootFileName="gargantua.root";
// Create and enable statistics of the heap
TStorage MyHeap;
MyHeap.EnableStatistics();
// Print out the memory state once before
cout << "Before\n";
MyHeap.PrintStatistics();
// Main loop : write 10 times in the file
for ( int i_loop=0 ; i_loop<10 ; i_loop++ ) {
// Open, fill and close the root file
ProcessFile(RootFileName);
// Print out the memory state
cout << "After " << i_loop+1 << " pass\n";;
MyHeap.PrintStatistics();
// Print out list of root classes
cout << "------List of current root classes----------\n";
AllClassesList = new TIter(MyRoot.GetListOfClasses());
while ( (obj = AllClassesList->Next()) ) {
cout << obj->GetName() << " "
<< "On Heap:" << PrintBool(obj->IsOnHeap()) << " "
<< "Zombie:" << PrintBool(obj->IsZombie()) << endl;
}
delete AllClassesList;
}
// Print out list of root classes and delete them
cout << "--------List of current root classes----------\n";
AllClassesList = new TIter(MyRoot.GetListOfClasses());
while ( (obj = AllClassesList->Next()) ) {
cout << obj->GetName() << " "
<< "On Heap:" << PrintBool(obj->IsOnHeap()) << " "
<< "Zombie:" << PrintBool(obj->IsZombie()) << endl;
// Suppress all classes on the heap
delete obj;
}
delete AllClassesList;
}