Bonjour Rene, I have applied your advice, although the heap contains plenty of objects related to the histogram. I observe the following after 10 iterations : - with my version (no pointer and use of the static member function Open) Total allocated memory : 77972 - with your proposal (with pointer, without the function Open, but with constructor and destructor each time) Total allocated memory : 73692 So my gain is 5.8% :-( If you look carefully at the heap, you will see that a TFile has appeared! Anyway I have put in comments all the histogram operation (creation and read out) and got down to 37966 :-| The heap now contains of course only the TFile class. In conclusion, it is not only a problem with TFile, AND the problem with TFile is still not solved. By looking shortly at the header of TFile, I have noticed some static declarations : static Double_t fgBytesWrite; static Double_t fgBytesRead; static const Int_t kBegin; static const Char_t kUnits; Some are also in TDirectory.h from which TFile derivates. Could these variables responsible for the memory leak ? Thanks, David Gourio On Mon, 5 Apr 1999, Rene Brun wrote: >Hi David, >If you look at the prototype of TFile::Open, you will see that this >is a static function returning a TFile object. >I have modified your function ProcessFile such that you do not get >a memory leak. > >Rene Brun > > >void ProcessFile(char * RootFileName) { > > 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 = new TFile(RootFileName,"CREATE","Gros appetit"); > } > else { > // File already exists > RH_File = new TFile(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(); > delete RH_File; >} > > >On Wed, 31 Mar 1999, David Gourio wrote: > >> Hi Rooters, >> >> 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; >> >> >> } >> >> >> >> > > ======================================================================== 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
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:31 MET