Re: Memory consumption is proportional to number of event

From: Takeaki Toeda (Takeaki.Toeda@cern.ch)
Date: Wed Jun 09 1999 - 11:42:10 MEST


Thank you very much for good advices.

6/9/99 9:00 AMRene.Brun@cern.ch

>Hi Take-Aki,
>In your class Event, you have a data member "device".
>When you write the TTree, you probably call Event::ReadDeviceRecord.
>This function creates a new Device object "Device *device = new
>Device();
>You add this object in a TObjArray. After the statement
>  deviceArray->Add(device);
>you should reset device
>   device = 0;
>or you should declare this member to be non-persistent
> Device  *device;  //! where ! means non-persistent in the header file.
Does this mean following?

// *device  ---> Device *device
  Int_t Event::ReadDeviceRecord(){
   Device *device = new Device();
   device->GetHeader();
   device->ReadData();
   deviceArray->Add(device);
   int size = device->GetRecordSize() + 2;
   return size;
 }
 
>With your current implementation, what happens is the following:
>When writing the Tree, device points to an active object. This object is
>Streamed. There is also a reference in the TObjArray. Root will save the 
object
>only once.
>When reading, the object is allocated to device and you never delete this 
object.
I defined destructor in liake a follawing, so I think this object added 
to 
TObjectArray is delete.

 Event::~Event(){
   deviceArray->Delete();
   delete deviceArray;
}

>To detect this kind of memory leak, you can add the statement
>   gObjectTable->Print();
I checked this statistics, but this value is stable, not increase.

>for example at the end of your Event destructor. (#include
>"TObjectTable.h")
>To get the correct statistics, you must activate the memory stats in
>your .rootrc file. example
>
># Activate memory statistics (size and cnt is used to trap allocation of
># blocks of a certain size after cnt times)
>Root.MemStat:            1
>Root.ObjectStat:         1
I checked this problem in intractive root by using macro.
But Memomry consumption is stable.
 
I thought reson of this problem is without root part,
but this problem dosen't happen without tree->GetEvent().

Oh--! Very strange...


>
>
>Let me know.
>
>Rene Brun
>
>
>Takeaki Toeda wrote:
>> 
>> Hello,
>> 
>> I have a data analysis program using TTree.
>> This program has a serius memory consumption in reading event from Tree.
>> 
>> I deleted member object in event destructor.
>> But memeory consumption is proprotional to number of event in reading
>> event
>> and lastly it reach to 100MB.
>> 
>> What do you know the idea to solve this problem?
>> Following is a Event.h and Event.cc.
>> 
>> Take-Aki TOEDA
>> 
>> --------------- Event.h --------------------
>> 
>> #ifndef Event_h
>> #define Event_h
>> #include <TObject.h>
>> #include <TObjArray.h>
>> #include <Device.h>
>> 
>> class Event : public TObject{
>>  public:
>>   Event();
>>   virtual ~Event();
>>   Int_t GetHeader();
>>   Int_t GetHeaderSize();
>>   void ShowHeader();
>>   void ShowDevice();
>>   Int_t GetDeviceType();
>>   Int_t GetEventSize();
>>   Int_t GetEventTypeSize();
>>   Int_t ReadDeviceRecord();
>>   Int_t GetData(int,int);
>>   void  ShowDeviceRecord(int);
>> 
>>  private:
>>   Short_t Size;
>>   Short_t EvtTypSize;
>>   Device *device;
>>   TObjArray *deviceArray;
>>   ClassDef(Event,1)
>> };
>> #endif
>> 
>> ---------------- Event.cc --------------
>> 
>> #include <Event.h>
>> #include <iostream.h>
>> 
>> ClassImp(Event)
>> 
>> Short_t *buffer;
>> Int_t dbglvl;
>> Int_t PedestalFlag;
>> 
>> Event::Event(){
>>   deviceArray = new TObjArray(40,0);
>> }
>> 
>> Event::~Event(){
>>   deviceArray->Delete();
>>   delete deviceArray;
>> }
>> 
>> Int_t Event::GetHeader(){
>>   Size       = *(buffer++);
>>   EvtTypSize = *(buffer++);
>>   ShowHeader();
>>   return 1;
>> }
>> 
>> void Event::ShowHeader(){
>>   if(dbglvl == 1){
>>     cout << " EventSize = " << Size
>>          << " EvtTypSiz = " << EvtTypSize
>>          << endl;
>>   }
>> }
>> 
>> Int_t Event::GetHeaderSize(){return 2;}
>> Int_t Event::GetEventSize(){ return (Int_t)Size;}
>> Int_t Event::GetEventTypeSize(){ return (Int_t)EvtTypSize;}
>> 
>> Int_t Event::ReadDeviceRecord(){
>>   device = new Device();
>>   device->GetHeader();
>>   device->ReadData();
>>   deviceArray->Add(device);
>>   int size = device->GetRecordSize() + 2;
>>   return size;
>> }
>> 
>> void Event::ShowDeviceRecord(Int_t index){
>>   ((Device*)deviceArray->At(index))->ShowData();
>> }
>> 
>> TObjArray *Event::GetDeviceArray(){
>>   return deviceArray;
>> }
>> 
>> Int_t Event::GetData(Int_t slot,Int_t ch){
>>   Device *device;
>>   Int_t nSlot;
>>   Int_t data = -999;
>>   Int_t entries = deviceArray->GetEntries();
>>   for(Int_t i=0;i<entries;i++){
>>     device = (Device*)deviceArray->At(i);
>>     nSlot = device->GetSlotNumber();
>>     if(nSlot == slot) data = ((Data*)device->GetData(ch))->GetData();
>>   }
>>   if(data == -999) {
>>     cout << "No module in the slot!" << endl;
>>   }
>> 
>> return data;
>> }
>> 
>> Int_t Event::GetDeviceType(){
>> return device->GetDeviceType();
>> }
>



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