Help to release memory

Dear ROOTers,

I have a macro to analysis my simulation data of a certain reaction. For each reaction event, I need to read the charges induced in each pad and save this information into a two dimensional array for further analysis. I wrote my macro in the following way:
void reader(char* inputSimFile, char* inputDigiFile, Int_t bw=3, Int_t mw=2, Int_t verb=0,
            Int_t minReactionNumber=0, Int_t maxReactionNumber=0){

  gROOT->SetStyle("Default");
  gStyle->SetOptTitle(0);
  gStyle->SetOptStat(1);
  gStyle->SetOptFit(0);

  Int_t VERBOSE=verb; // verbose = 0: do not print this information
                      //         = 1: print all information

  Int_t beamWidth   = bw;
  Int_t marginWidth = mw;

  Double_t PI=3.1415926535897932384626433;
  Double_t rad=180./PI;

  Int_t numberOfRows   = thePadsGeometry.GetNumberOfRows();
  Int_t numberOfColumns= thePadsGeometry.GetNumberOfColumns();

  // "raw data", output of ActarSim
  TFile *simFile = TFile::Open(inputSimFile);
  TTree *eventTree = (TTree*)simFile->Get("The_ACTAR_Event_Tree");

  // digitization data, output of digitizationMacro
  TFile *digiFile = TFile::Open(inputDigiFile);
  TTree *digiTree = (TTree*)digiFile->Get("digiTree");

  TClonesArray* padSignalCA = new TClonesArray("ActarPadSignal",50);
  digiTree->SetBranchAddress("padSignals",&padSignalCA);

  // information for each reactions
  Int_t nevents    = eventTree->GetEntries();
  Int_t nReactions = nevents/2 -1; // number of reactions calculated

  // ******************  starting loop over reactions *******************//
  for(Int_t i=minReactionNumber; i<=maxReactionNumber; i++){

      Double_t **padCharge = new Double_t*[numberOfRows];
      for(Int_t j=0; j<numberOfRows; j++){
        padCharge[j] = new Double_t[numberOfColumns];
      }

      // clean arraies for pad charge and time
      for(Int_t j=0;j<numberOfRows;j++){
        for(Int_t k=0;k<numberOfColumns;k++){
          padCharge[j][k]=0.;
        }
      }

    Int_t nb = 0;
    for(Int_t j=2*i; j<=2*i+1; j++){ // beam: 2*i, primaries 2*i+1

      // clear TClonesArray before filling them
      padSignalCA ->Clear();

      nb +=  digiTree->GetEvent(j);
      nb += eventTree->GetEvent(j);

      Int_t padsPerEvent = padSignalCA->GetEntries();

      if(padsPerEvent>0) {
        for(Int_t h=0;h<padsPerEvent;h++){
          ActarPadSignal* padSignal = new ActarPadSignal;
          padSignal = (ActarPadSignal*) padSignalCA->At(h);

          padCharge[padSignal->GetPadRow()-1][padSignal->GetPadColumn()-1]
                 += padSignal->GetChargeDeposited();
        }
      }
    }

   for (Int_t j=0; j<numberOfRows; j++ )
     delete [](padCharge[j]);
   delete [] padCharge;

  cout << "********** reaction " << i << " finished! *************" << endl;
  }// end of one reaction
}  // end of analysis

I would like the memory taken by the padCharge[][] can be released every time when the analysis of one reaction is finished. However, it does not work as I expected. The memory used by this macro will increase with the number of reactions analysed. For example, if I loop over 2000 reactions, it will consume arround 700 MB of memory, which is too much because my PC has only 2 GB of memory and I want to analysis 10000 reactions every time :frowning:

Could anyone tell me what’s wrong in this macro? How to release the memory every time when one loop is finished?

Thanks in advance!

best regards,

Pang

You have a huge leak in your code when doing:

ActarPadSignal* padSignal = new ActarPadSignal; padSignal = (ActarPadSignal*) padSignalCA->At(h);
You do not need to create the new ActarPadSignal object since it is
already in the collection padSignalCA.

You also have a crazy innefficient allocation of arrays of constant sizes in your loop.
You can move the creation/destruction of teh arrays outside the loop.
see proposed new code below;

Rene

[code]
void reader(char* inputSimFile, char* inputDigiFile, Int_t bw=3, Int_t mw=2, Int_t verb=0,
Int_t minReactionNumber=0, Int_t maxReactionNumber=0){

gROOT->SetStyle(“Default”);
gStyle->SetOptTitle(0);
gStyle->SetOptStat(1);
gStyle->SetOptFit(0);

Int_t VERBOSE=verb; // verbose = 0: do not print this information
// = 1: print all information

Int_t beamWidth = bw;
Int_t marginWidth = mw;

Double_t PI=3.1415926535897932384626433;
Double_t rad=180./PI;

Int_t numberOfRows = thePadsGeometry.GetNumberOfRows();
Int_t numberOfColumns= thePadsGeometry.GetNumberOfColumns();

// “raw data”, output of ActarSim
TFile *simFile = TFile::Open(inputSimFile);
TTree eventTree = (TTree)simFile->Get(“The_ACTAR_Event_Tree”);

// digitization data, output of digitizationMacro
TFile *digiFile = TFile::Open(inputDigiFile);
TTree digiTree = (TTree)digiFile->Get(“digiTree”);

TClonesArray* padSignalCA = new TClonesArray(“ActarPadSignal”,50);
digiTree->SetBranchAddress(“padSignals”,&padSignalCA);

// information for each reactions
Int_t nevents = eventTree->GetEntries();
Int_t nReactions = nevents/2 -1; // number of reactions calculated

Double_t *padCharge = new Double_t[numberOfRows];
for(Int_t j=0; j<numberOfRows; j++){
padCharge[j] = new Double_t[numberOfColumns];
}

// ****************** starting loop over reactions *******************//
for(Int_t i=minReactionNumber; i<=maxReactionNumber; i++){

  // clean arrays for pad charge and time
  for(Int_t j=0;j<numberOfRows;j++){
    for(Int_t k=0;k<numberOfColumns;k++){
      padCharge[j][k]=0.;
    }
  }

Int_t nb = 0;
for(Int_t j=2*i; j<=2*i+1; j++){ // beam: 2*i, primaries 2*i+1

  // clear TClonesArray before filling them
  padSignalCA ->Clear();

  nb +=  digiTree->GetEvent(j);
  nb += eventTree->GetEvent(j);

  Int_t padsPerEvent = padSignalCA->GetEntries();

  if(padsPerEvent>0) {
    for(Int_t h=0;h<padsPerEvent;h++){
      //ActarPadSignal* padSignal = new ActarPadSignal;
      ActarPadSignal*padSignal = (ActarPadSignal*) padSignalCA->At(h);

      padCharge[padSignal->GetPadRow()-1][padSignal->GetPadColumn()-1]
             += padSignal->GetChargeDeposited();
    }
  }
}

cout << “********** reaction " << i << " finished! *************” << endl;
}// end of one reaction
for (Int_t j=0; j<numberOfRows; j++ )
delete ;
delete [] padCharge;

} // end of analysis[/code]

Thank you. My problem is solved :slight_smile: