Re: Memory consumption is proportional to number of event

Takeaki Toeda (Takeaki.Toeda@cern.ch)
Wed, 9 Jun 99 11:42:10 +0200


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();
>> }
>