From c08f45aab3a9f177f85cc35613a8c00ab980b195 Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Sat, 16 Oct 2010 17:23:52 +0000 Subject: [PATCH] More improvements in TMemStat::Show // // TMemStat::Show creates 3 canvases. // -In canvas1 it displays a dynamic histogram showing for pages (10 kbytes by default) // the percentage of the page used. // A summary pave shows the total memory still in use when the TMemStat object // goes out of scope and the average occupancy of the pages. // The average occupancy gives a good indication of the memory fragmentation. // // -In canvas2 it displays the histogram of memory leaks in decreasing order. // when moving the mouse on this canvas, a tooltip shows the backtrace for the leak // in the bin below the mouse. // // -In canvas3 it displays the histogram of the nbigleaks largest leaks (default is 20) // for each leak, the number of allocs and average alloc size is shown. // // // Simply do: // root > TMemStat::Show() // or specifying arguments // root > TMemStat::Show(0.01,20,"mydir/mymemstat.root"); // // The first argument to Show is the percentage of the time of the original job // that produced the file after which the display is updated. By default update=0.01, // ie 100 time intervals will be shown. // The second argument is nbigleaks. // The third argument is the imput file name (result of TMemStat). // If this argument is omitted, the script will take the most recent file // generated by TMemStat. git-svn-id: http://root.cern.ch/svn/root/trunk@36362 27541ba8-7e3a-0410-8455-c3a389f83636 --- misc/memstat/src/TMemStat.cxx | 1 + tree/treeviewer/src/TMemStatShow.cxx | 90 +++++++++++++++++++--------- 2 files changed, 64 insertions(+), 27 deletions(-) diff --git a/misc/memstat/src/TMemStat.cxx b/misc/memstat/src/TMemStat.cxx index 4584114b7ed..e106b111850 100644 --- a/misc/memstat/src/TMemStat.cxx +++ b/misc/memstat/src/TMemStat.cxx @@ -49,6 +49,7 @@ // in the bin below the mouse. // // -In canvas3 it displays the histogram of the nbigleaks largest leaks (default is 20) +// for each leak, the number of allocs and average alloc size is shown. // // // Simply do: diff --git a/tree/treeviewer/src/TMemStatShow.cxx b/tree/treeviewer/src/TMemStatShow.cxx index fdbf7051c8c..eacbaea3ad8 100644 --- a/tree/treeviewer/src/TMemStatShow.cxx +++ b/tree/treeviewer/src/TMemStatShow.cxx @@ -35,6 +35,7 @@ // in the bin below the mouse. // // -In canvas3 it displays the histogram of the nbigleaks largest leaks (default is 20) +// for each leak, the number of allocs and average alloc size is shown. // // // Simply do: @@ -78,6 +79,9 @@ Double_t *gV2; //pointer to V1 array of TTree::Draw Double_t *gV3; //pointer to V1 array of TTree::Draw Double_t *gV4; //pointer to V1 array of TTree::Draw + TCanvas *gC1; //pointer to anvas shoing allocs/deallocs vs time + TCanvas *gC2; //pointer to canvas with leaks in decreasing order + TCanvas *gC3; //pointer to canvas showing the main leaks //___________________________________________________________________________ void TMemStatShow::Show(double update, int nbigleaks, const char* fname) @@ -174,10 +178,10 @@ void TMemStatShow::Show(double update, int nbigleaks, const char* fname) gHalloc = new TH1D("gHalloc",Form("%s;pos;number of mallocs",fname),nbins,ivmin,ivmax); gHfree = new TH1D("gHfree", Form("%s;pos;number of frees",fname),nbins,ivmin,ivmax); //open a canvas and draw the empty histogram - TCanvas *c1 = new TCanvas("c1","c1",1200,600); - c1->SetFrameFillColor(kYellow-3); - c1->SetGridx(); - c1->SetGridy(); + gC1 = new TCanvas("gC1","c1",1200,600); + gC1->SetFrameFillColor(kYellow-3); + gC1->SetGridx(); + gC1->SetGridy(); h->Draw(); //create a TPaveText to show the summary results TPaveText *pvt = new TPaveText(.5,.9,.75,.99,"brNDC"); @@ -250,7 +254,7 @@ void TMemStatShow::Show(double update, int nbigleaks, const char* fname) //update canvas at regular intervals updateLast = time; h->SetEntries(i); - c1->Modified(); + gC1->Modified(); pvt->GetListOfLines()->Delete(); Double_t mbytes = 0; Int_t nonEmpty = 0; @@ -268,7 +272,7 @@ void TMemStatShow::Show(double update, int nbigleaks, const char* fname) pvt->AddText("(for non empty pages only)"); ptime->SetLabel(Form("%g sec",time)); - c1->Update(); + gC1->Update(); gSystem->ProcessEvents(); } } @@ -307,11 +311,11 @@ void TMemStatShow::Show(double update, int nbigleaks, const char* fname) gHleaks->SetEntries(nleaks); //open a second canvas and draw the histogram with leaks in decreasing order - TCanvas *c2 = new TCanvas("c2","c2",1200,600); - c2->SetFrameFillColor(kCyan-6); - c2->SetGridx(); - c2->SetGridy(); - c2->SetLogy(); + gC2 = new TCanvas("gC2","c2",1200,600); + gC2->SetFrameFillColor(kCyan-6); + gC2->SetGridx(); + gC2->SetGridy(); + gC2->SetLogy(); gHleaks->SetFillColor(kRed-3); if (nleaks > 1000) gHleaks->GetXaxis()->SetRange(1,1000); gHleaks->Draw(); @@ -319,24 +323,24 @@ void TMemStatShow::Show(double update, int nbigleaks, const char* fname) if (named) tmachine.DrawText(0.01,0.01,named->GetTitle()); //construct the tooltip - TRootCanvas *rc = (TRootCanvas *)c2->GetCanvasImp(); + TRootCanvas *rc = (TRootCanvas *)gC2->GetCanvasImp(); TGMainFrame *frm = dynamic_cast<TGMainFrame *>(rc); // create the tooltip with a timeout of 250 ms if (!gTip) gTip = new TGToolTip(gClient->GetDefaultRoot(), frm, "", 250); - c2->Connect("ProcessedEvent(Int_t, Int_t, Int_t, TObject*)", + gC2->Connect("ProcessedEvent(Int_t, Int_t, Int_t, TObject*)", "TMemStatShow", 0, "EventInfo(Int_t, Int_t, Int_t, TObject*)"); - //fill histogram htotleaks accumulating in the same bin all leaks - //from btids having identical nchar first characters - //open a third canvas and draw the histogram with the nbigleaks largest leaks - TCanvas *c3 = new TCanvas("c3","c3",1200,600); - c3->SetFrameFillColor(kCyan-6); - c3->SetGridx(); - c3->SetGridy(); - c3->SetLogx(); - c3->SetLeftMargin(0.05); - c3->SetRightMargin(0.7); + gC3 = new TCanvas("gC3","c3",1200,600); + gC3->SetFrameFillColor(kCyan-6); + gC3->SetGridx(); + gC3->SetGridy(); + gC3->SetLogx(); + gC3->SetLeftMargin(0.05); + gC3->SetRightMargin(0.7); + + //fill histogram htotleaks accumulating in the same bin all leaks + //from btids having identical nchar first characters TH1I *htotleaks = new TH1I("htotleaks","main leaks sorted by btids",100,0,0); Int_t l; for (l=1;l<=nleaks;l++) { @@ -344,25 +348,56 @@ void TMemStatShow::Show(double update, int nbigleaks, const char* fname) TMemStatShow::FillBTString(l,1,btstring); htotleaks->Fill(btstring.Data()+2,gHleaks->GetBinContent(l)); } + Double_t tsize = 0.03; + if (nbigleaks > 30) tsize = 0.02; htotleaks->LabelsOption(">"); htotleaks->GetXaxis()->SetRange(1,nbigleaks); - htotleaks->GetXaxis()->SetLabelSize(0.03); + htotleaks->GetXaxis()->SetLabelSize(tsize); + htotleaks->GetYaxis()->SetLabelSize(tsize); htotleaks->SetFillColor(kBlue-3); htotleaks->Draw("hbar2 y+"); //now loop on all the sorted bins and count the number of leaks + Double_t xr = 0.96*gC3->GetLeftMargin(); + Double_t xr2 = 1.04*gC3->GetLeftMargin(); + Double_t ytop = 1-gC3->GetTopMargin(); + Double_t ylow = gC3->GetBottomMargin(); + Double_t dy = (ytop-ylow)/nbigleaks; TString btstring; + TText tnl; + tnl.SetNDC(); + tnl.SetTextSize(tsize); + tnl.SetTextAlign(32); + TText tnl2; + tnl2.SetNDC(); + tnl2.SetTextSize(tsize); + tnl2.SetTextAlign(12); + tnl2.SetTextColor(kYellow); for (Int_t lb=1;lb<=nbigleaks;lb++) { + if (htotleaks->GetBinContent(lb) <= 0) continue; const char *label = htotleaks->GetXaxis()->GetBinLabel(lb); Int_t nchlabel = strlen(label); + if (nchlabel == 0) htotleaks->GetXaxis()->SetBinLabel(lb,"???"); Int_t nl =0; for (l=1;l<=nleaks;l++) { btstring = ""; TMemStatShow::FillBTString(l,1,btstring); - if (!strncmp(btstring.Data()+2,label,nchlabel)) nl++; + if (nchlabel > 0) { + if (!strncmp(btstring.Data()+2,label,nchlabel)) nl++; + } else { + if (btstring.Length() == 0) nl++; + } } - printf("bin %d, nl=%d, label=%s\n",lb,nl, label); + Double_t yr = ylow +(lb-0.5)*dy; + tnl.DrawText(xr,yr,Form("%d",nl)); + Int_t nbmean = Int_t(htotleaks->GetBinContent(lb)/nl); + if (lb == 1) tnl2.DrawText(xr2,yr,Form("%d bytes/alloc",nbmean)); + else tnl2.DrawText(xr2,yr,Form("%d",nbmean)); } + tnl.DrawText(xr,ytop+0.015,"nallocs"); + tnl.DrawText(1-gC3->GetRightMargin(),0.5*ylow,"nbytes"); + //draw producer identifier + if (named) tmachine.DrawText(0.01,0.01,named->GetTitle()); } @@ -374,7 +409,7 @@ void TMemStatShow::EventInfo(Int_t event, Int_t px, Int_t , TObject *selected) gTip->Hide(); if (event == kMouseLeave) return; - Double_t xpx = gPad->AbsPixeltoX(px); + Double_t xpx = gC2->AbsPixeltoX(px); Int_t bin = gHleaks->GetXaxis()->FindBin(xpx); if (bin <=0 || bin > gHleaks->GetXaxis()->GetNbins()) return; Int_t nbytes = (Int_t)gHleaks->GetBinContent(bin); @@ -413,6 +448,7 @@ void TMemStatShow::FillBTString(Int_t bin,Int_t mode,TString &btstring) Int_t nch = strlen(title); if (nch < 10) continue; if (strstr(title,"memstat")) continue; + if (strstr(title,"TMemStatHook")) continue; char *bar = strchr(title+5,'|'); if (!bar) bar = title; -- GitLab