Memory leakage when cloning a canvas

Dear Rooters,

I am stuck with a problem of memory leakage since 2 weeks now. I am developing a GUI to display simulated events inside a detector. I’m using ROOT GUI stuff and also TGeo* for the detector. I have basically two frames: one for the 3D view and the other one for 2D visualization.

I am doing almost everything inside the 3D canvas: first, I construct the detector volumes, then, given this geometry, I plot the different hits using G3D class such as TPolyLine3D or TMarker3DBox. These “hits” objects are stored in a TObjArray and, for each new event, I delete the content of this TObjArray. So no memory leak at this stage and this is working well.

Second step consists of showing the event in 2D. So, I get the 3D canvas with all the structures previously plotted, make a clone of it in order to modify the view i.e. changing the “perspective” view to “parallel” one. Again, for each event, I clear the 2D canvas using Clear method.

The code looks like that


// First construct the detector
fCanvas3D->cd ();

TGeoManager* geo_mgr = new TGeoManager("EventViewer", "3D Event Viewer");
TGeoVolume* world = gGeoManager->MakeBox("TOP", NULL, fDetector.get_length ()/2., fDetector.get_width  ()/2., fDetector.get_height ()/2.);

...
// Then plot each event in 3D

for (unsigned int iEvent =...) {
  fObjArray->Delete ();
  fCanvas3D->cd ();

  TMarker3DBox* vertex = new TMarker3DBox ();
  fObjArray->Add (vertex);
  ...

  // 2D part
  if (fCanvas2D) {
    fCanvas2D->Clear ();
    delete fCanvas2D;
  }

  fRootEmbeddedCanvas->AdoptCanvas ((TCanvas*) fCanvas3D->Clone ("2DView"));
  fCanvas2D = fRootEmbeddedCanvas->GetCanvas ();
  // then I modify the 2D canvas to switch to the parallel view
}

When I activate the 2D view, I get memory leakage (not so huge but enough to slow down the event visualization). I read carrefully Chapter 8 about Object Ownership, search on the forum … I did not succeed to solve this problem.

One last remark: I am compiling the code with ROOT v5.27.02. It is pretty hard to provide files since the different part of the code are written in different class and so different files. I try to give an idea of what I am doing in the previous code. I hope to have included the most relevant part of the code but I am not sure it will be enough.

If someone can help me or give me some hints,

Thanks a lot,
Xavier G.

I am afraid that we will need a running subset of your code to figure out what happens.

Rene

Dear René,

Attached is a ROOT macro trying to summarize the different step of my program. At least, the macro reproduces the memory leakage when I enable the 2D view i.e. when cloning is done. I did it quickly this morning so I hope not to have done too much mistakes. Of course, the detector construction and the vertex generation are totally stupid :smiley:.

Thanks for your help,
Xavier
test_clone.C (3.28 KB)

Hi Xavier,

run the version of test_clone.C in attachment (I have added 2 lines) to print the table of objects every 10 events, such that you can see which objects are leaking.
Before running modify $ROOTSYS/etc/system.rootrc with the following statements (replace)

[code]# Activate memory statistics (size and cnt is used to trap allocation of

blocks of a certain size after cnt times).

Root.MemStat: 1
Root.MemStat.size: -1
Root.MemStat.cnt: -1
Root.ObjectStat: 1[/code]
test_clone.C (3.35 KB)

Hi René,

I changed my system.rootrc file and did your trick to see which Object were leaking. I think you already knew the answer :slight_smile: since all my TGeo stuff is leaking. So frankly speaking :slight_smile:, how I solve that ? Or how I tell the second 2D canvas to be the owner of the cloned TGeoXXX ? Then, the Clean method will be able to delete the copied TGeoXXX, right ?
The solution is not obvious for me since everything is cleared properly except the TGeo part. Did I miss something important in ROOT fundamentals :slight_smile: ?

Thanks again for your help,
Xavier

By cloning the canvas containing a TGeoVolume you continue to add to the main geometry structure.
I suggest to change and simplify your logic in the way shown in the attachment.
Look at commented lines and lines with “//<======”

Rene
test_clone.C (3.59 KB)

Hi René,

I get your point and so I will try to rethink my program in order to separate the detector construction using TGeo stuff (which has nothing to see with the canvas used) and the way to plot the event. Actually, what I am losing is all the benefit of plotting the detector and events in the 3D canvas and then, to get the 2D view, I just had to do SetParallel to my TVeiw3D and use Side, Top, Front methods. Without cloning I will have to replot things in both canvases, but since the objects already exists, I guess recalling the Draw method will not take too much time and ressources (at least less than cloning the entire canvas).

Thanks again for your help,
Xavier