memory leak

From: Hans Wenzel (wenzel@ekp.physik.uni-karlsruhe.de)
Date: Wed Oct 20 1999 - 12:03:04 MEST


Dear Root team


I was experimenting with estimating the right size of a TMapFile since i
am using root in an online environment and
I want to make sure that my users don't fill more stuff into shared
memory than space is available and cause a segmentation fault.
To do this I wrote a little C++ program that i have attached to this
mail.
Executing it transformed my Linux boxes into zombies that could be
brought back to life only by rebooting. This was true for programs
compiled with egcs or kai KCC 9(SUSE 6.1 AND 6.2) with rot 2.22.06 as
well as with the latest 2.23.04. It looks like if I set the size of the
TMapFile too small  (say smaller than 30000 in this example) a big
memory leak is created although only  a fraction of the available space
should be  used  up.
I have to admit that working with TMapFile is getting very frustrating.
I think a robust program should return an error status that one can deal
with in case that one tries to put more objects into shared memory than
place is available. Getting an segmentation violation is just
not my idea of a robust program. Also the input should be checked e.g.
what is the minimal size that i can allocate a TMapFile with?
Then if the program reports that 40 kbyte are allocated and only 13k are
used i would think there are still 27k available.
Of course i could just make the Mapfile huge enough but that doesn't
seem to be a very elegant solution.



cheers



hans




--
________________________________________________________________________________
Hans Wenzel                         | Phone:(721) 608 3418
Inst. für Experimentelle Kernphysik |       (721) 96453 45 (home)
Universität Karlsruhe               | Fax:  (721) 607 262               .~.   L
Engesserstr. 7                      | email: wenzel@fnal.gov            /V\   I
D-76128 Karlsruhe                   | http://kcdf1.fnal.gov/~wenzel/   // \\  N
Germany                             |                                 /(   )\ U
______________________________________________________________________ ^`~'^__X_




// This programm creates 3 histogramms and writes them to shared memory to
//  be read by server
// To run this demo do the following:
//   - run Producer.exe so that the memory map file is created and histograms
//     are produced
//   - run Server.exe to wait for socket connections
//   - run this HistoDisplayMain.exe to open socket connection and to display 
//     the histograms
//  Hans Wenzel IEKP Karlsruhe 
//  Frank Hartmann IEKP Karlsruhe
#ifndef __CINT__
#include <iostream.h>
#include "TROOT.h"
#include "TH1.h"
#include "TH2.h"
#include "TRandom.h"
#include "TMapFile.h"
#include "TSystem.h"
#include "TDirectory.h"
int main ()
{
   TROOT producer("producer","Simple histogram producer to shared memory ");
#endif
#ifdef __CINT__
   {
   gROOT->Reset();
#endif

      //Now create the memory map file

      TMapFile *mfile;
      mfile = TMapFile::Create("hsimple.map","RECREATE", 30000,
                            "Demo memory mapped file with histograms");
      Int_t size  = mfile->GetSize();
      Int_t * breakval    = (Int_t*)mfile->GetBreakval();
      Int_t *baseaddress = (Int_t*)mfile->GetBaseAddr();      
      Int_t usedspace  = (breakval - baseaddress);
      Int_t whatisleft = size -usedspace;
     float percentage = ((float)usedspace*100.)/(float)size;
      cout << "current break value:     "<<mfile->GetBreakval()
           << "   current base value:   " <<  mfile->GetBaseAddr() <<endl;
      cout << "size of shared memory :  "<<mfile->GetSize()
           << "   used space (B): " << usedspace
	   << "   frac. of total(%):  "  << percentage<< endl;
      cout << endl;
   // Print status of mapped file

   // Create  1d and  2d  histograms. These objects will
   // be automatically added to the current directory, i.e. mfile.
      TH1F *histo1; 
      TH1F *histo2;
      TH2F *histo3;

      histo1 = new TH1F("histo1","Muon Energy",50,0,30);
      histo1->SetXTitle("muon energy");
      histo1->SetYTitle("event count");
      histo1->SetFillColor(48);

      histo2 = new TH1F("histo2","Muon Pt",50,0,30);
      histo2->SetXTitle("muon pt");
      histo2->SetYTitle("event count");
      histo2->SetFillColor(48);
     
      histo3 = new TH2F("histo3","Muon py vs px",50,0,30,50,0,30);
      histo3->SetXTitle("muon px");
      histo3->SetYTitle("muon py");

      mfile->Add(histo1);
      mfile->Add(histo2); 
      mfile->Add(histo3);
      // now check how much space is left in shared memory
      // stop if not enough memory available

      size  = mfile->GetSize();
      breakval    = (Int_t*)mfile->GetBreakval();
      baseaddress = (Int_t*)mfile->GetBaseAddr();      
      usedspace  = (breakval - baseaddress);
      whatisleft = size -usedspace;
      percentage = ((float)usedspace*100.)/(float)size;
      cout << "current break value:     "<<mfile->GetBreakval()
           << "   current base value:   " <<  mfile->GetBaseAddr() <<endl;
      cout << "size of shared memory :  "<<mfile->GetSize()
           << "   used space (B): " << usedspace
	   << "   frac. of total(%):  "  << percentage<< endl;
      cout << endl;
      cout << " now list objects in memory" << endl;
gDirectory->ls("m") ;
      cout << " now list objects in files " << endl;
gDirectory->ls("d") ;
      cout << " now list objects in all files " << endl;
gROOT->GetListOfFiles()->ls();
TList* li = gDirectory->GetList();
TBuffer* b;   
UInt_t ssize=0;  // estimated value of map-file size

TIter next(li);
TObject* obj;
int ii=0;
 cout << "minimal buffer size:" << TBuffer::kMinimalSize<< endl;
 cout << "default map size:" <<TMapFile::kDefaultMapSize<< endl;
while((obj=next())) // loop over all objects in list
{
   b = new TBuffer(TBuffer::kWrite, TBuffer::kMinimalSize);
   obj->Streamer(*b);   
   ssize +=  b->BufferSize();
   ++ii;
   cout << ii<< "   size:   " << ssize << endl;
   delete b;
}
   cout << ii<< "   size:   " << ssize << endl;

      if (whatisleft<0) 
	  {
	   cout << "shared memory is full" << endl;
	  //          exit();
	  } 

      mfile->Update();

      size  = mfile->GetSize();
      breakval    = (Int_t*)mfile->GetBreakval();
      baseaddress = (Int_t*)mfile->GetBaseAddr();      
      usedspace  = (breakval - baseaddress);
      whatisleft = size -usedspace;
      percentage = ((float)usedspace*100.)/(float)size;
      cout << "current break value:     "<<mfile->GetBreakval()
           << "   current base value:   " <<  mfile->GetBaseAddr() <<endl;
      cout << "size of shared memory :  "<<mfile->GetSize()
           << "   used space (B): " << usedspace
	   << "   frac. of total(%):  "  << percentage<< endl;
      cout << endl;
   // Print status of mapped file and list its contents
      mfile->Print();
      mfile->ls();
gDirectory->ls("d") ;
      cout << " now list objects in all files " << endl;
gROOT->GetListOfFiles()->ls();
   Float_t muon_Energy,muon_Pt,muon_Px,muon_Py;
   int count = 0;
   // now start endless loop
   while (1) {
     //get random number for muon px and py:   
      gRandom->Rannor(muon_Px,muon_Py);
      muon_Px     = muon_Px + 10.;
      muon_Py     = muon_Py + 10.;
      muon_Pt     = sqrt(muon_Px*muon_Px+muon_Py*muon_Py);
      muon_Energy = sqrt(0.105*0.105+muon_Pt*muon_Pt);
      histo1->Fill(muon_Energy,1.0);
      histo2->Fill(muon_Pt,1.0);
      histo3->Fill(muon_Px,muon_Py,1.0);
      gSystem->Sleep(100);   // sleep for 0.1 seconds (don't swamp the system)
       
      if (count % 10 == 0) {
        //
        // memory map file is  is updated every 10 events.
        // (You might want to change this when processing
        // a lot of events.)
        //
        mfile->Update();       // updates all objects in shared memory
         }
       //       cout<<count<<endl;
      count++;

   }
  
}



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:41 MET