// @(#)root/treeviewer:$Id$
// Author: Rene Brun   21/09/2010

/*************************************************************************
 * Copyright (C) 1995-2010, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//___________________________________________________________________________
// Utility class post-processing the file generated by TMemStat (default memstat.root)
//
// TMemStat records all the calls to malloc and free and write a TTree
// with the position where the memory is allocated/freed , as well as
// the number of bytes.
//
// To use the class TMemStat, add the following statement at the beginning
// of your script or program
//     TMemStat mm("gnubuiltin");
// or in an interactive session do something like:
//    root > TMemStat mm("gnubuiltin");
//    root > .x somescript.C
//    root > .q
//
// another (may be more practical way) is to modify $ROOTSYS/etc/system.rootrc
// and activate the variable
//    Root.TMemStat:           1
//
// The file collected by TMemStat is named memstat_ProcessID and can be analyzed and results shown
// by executing the static function Show.
// When TMemStat is active it recors every call to malloc/free in a ROOT Tree.
// You must be careful when running jobs with many millions (or more) of calls
// to malloc/free because the generated Tree may become very large.
// The TMemStat constructor TMemStat(const char* system, Int_t buffersize, Int_t maxcalls)
// has its 3 arguments optional:
//   -system refers to the internal algorithm to compute the back traces.
//    the recommended value is "gnubuiltin"
//   -buffersize is the number of calls to malloc or free that can be stored in one memory buffer.
//    when the buffer is full, the calls to malloc/free pointing to the same location
//    are eliminated and not written to the final Tree. The default value 100000
//    is such that between 50 and 90% of the calls are eliminated depending on the application.
//    You can set buffersize <=1 to keep every single call to malloc/free.
//   -maxcalls can set a limit for the maximum number of calls to be registered in the Tree.
//    The default value is 5000000.
// The 3 arguments can be set  in $ROOTSYS/etc/system.rootrc
//    Root.TMemStat.system      gnubuiltin
//    Root.TMemStat.buffersize  100000
//    Root.TMemStat.maxcalls    5000000
//
// 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.
//  When moving the mouse on this canvas, a tooltip shows the backtrace for the allocations
//  at the address at the mouse position.
//
// -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.1,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.1,
// ie 10 time intervals will be shown.
// The second argument is nbigleaks. if <=0 canvas2 and canvas3 are not shown
// The third argument is the imput file name (result of TMemStat).
// If this argument is omitted, Show will take the most recent file
// generated by TMemStat.
//
// You can restrict the address range to be analyzed via TMemStatShow::SetAddressRange
// You can restrict the entry range to be analyzed via TMemStatShow::SetEntryRange
//
//Author: Rene Brun 7 July 2010
//___________________________________________________________________________

#include "TMemStatShow.h"
#include "TMath.h"
#include "TFile.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TStyle.h"
#include "TH1.h"
#include "TPaveText.h"
#include "TPaveLabel.h"
#include "TSystem.h"
#include "TGClient.h"
#include "TGToolTip.h"
#include "TRootCanvas.h"

   TTree     *TMemStatShow::fgT = 0;         //TMemStat Tree
   TH1D      *TMemStatShow::fgHalloc = 0;    //histogram with allocations
   TH1D      *TMemStatShow::fgHfree = 0;     //histogram with frees
   TH1D      *TMemStatShow::fgH = 0;         //histogram with allocations - frees
   TH1I      *TMemStatShow::fgHleaks = 0;    //histogram with leaks
   TH1I      *TMemStatShow::fgHentry = 0;    //histogram with entry numbers in the TObjArray
   TH1I      *TMemStatShow::fgHdiff = 0;     //histogram with diff of entry number between alloc/free

   TGToolTip *TMemStatShow::fgTip1 = 0;      //pointer to tool tip for canvas 1
   TGToolTip *TMemStatShow::fgTip2 = 0;      //pointer to tool tip for canvas 2
   TObjArray *TMemStatShow::fgBtidlist = 0;  //list of back trace ids
   Double_t  *TMemStatShow::fgV1 = 0;        //pointer to V1 array of TTree::Draw (pos)
   Double_t  *TMemStatShow::fgV2 = 0;        //pointer to V2 array of TTree::Draw (nbytes)
   Double_t  *TMemStatShow::fgV3 = 0;        //pointer to V3 array of TTree::Draw (time)
   Double_t  *TMemStatShow::fgV4 = 0;        //pointer to V4 array of TTree::Draw (btid)
   TCanvas   *TMemStatShow::fgC1 = 0;        //pointer to canvas showing allocs/deallocs vs time
   TCanvas   *TMemStatShow::fgC2 = 0;        //pointer to canvas with leaks in decreasing order
   TCanvas   *TMemStatShow::fgC3 = 0;        //pointer to canvas showing the main leaks

   Long64_t TMemStatShow::fgEntryFirst   = 0; //first address to process
   Long64_t TMemStatShow::fgEntryN       = 0; //number of addresses in bytes to process
   Long64_t TMemStatShow::fgAddressFirst = 0; //first entry to process
   Long64_t TMemStatShow::fgAddressN     = 0; //number of entries to process

//___________________________________________________________________________
void TMemStatShow::SetAddressRange(Long64_t nbytes, Long64_t first)
{
   //specify a memory address range to process (static function).
   // This function can be used to restrict the range of memory addresses
   // to be analyzed. For example whem TmemStat is run on a 64 bits machine and
   // the results visualized on a 32 bits machine, it might be necessary to
   // restrict the analysis range to the addresses below 2 Gigabytes, eg
   //   TMemStatShow::SetMemoryRange(500000000,0); //analyse only the first 500 MBytes
   // -first : first address to process (default is 0)
   // -nbytes : number of addresses in bytes to process starting at first
   //             if 0 (default), then all addresses are processed

   fgAddressFirst = first;
   fgAddressN     = nbytes;
}

//___________________________________________________________________________
void TMemStatShow::SetEntryRange(Long64_t nentries, Long64_t first)
{
   //specify a range of entries to process (static function)
   // -first : first entry to process (default is 0)
   // -nentries : number of entries to process starting at first
   //             if 0 (default), then all entries are processed
   // call this function when the amount of data collected in the Tree is large
   // and therefore making the analysis slow.

   fgEntryFirst = first;
   fgEntryN     = nentries;
}

//___________________________________________________________________________
void TMemStatShow::Show(double update, int nbigleaks, const char* fname)
{
   // function called by TMemStat::Show
   // Open the memstat data file, then call TTree::Draw to precompute
   // the arrays of positions and nbytes per entry.
   // update is the time interval in the data file  in seconds after which
   // the display is updated. For example is the job producing the memstat.root file
   // took 100s to execute, an update of 0.1s will generate 1000 time views of
   // the memory use.
   // the histogram hbigleaks will contain the nbigleaks largest leaks
   // if fname=="*" (default), the most recent file memstat*.root will be taken.


   TString s;
   if (!fname || strlen(fname) <5 || strstr(fname,"*")) {
      //take the most recent file memstat*.root
      s = gSystem->GetFromPipe("ls -lrt memstat*.root");
      Int_t ns = s.Length();
      fname = strstr(s.Data()+ns-25,"memstat");
   }
   printf("Analyzing file: %s\n",fname);
   TFile *f = TFile::Open(fname);
   if (!f) {
      printf("Cannot open file %s\n",fname);
      return;
   }
   fgT = (TTree*)f->Get("T");
   if (!fgT) {
      printf("cannot find the TMemStat TTree named T in file %s\n",fname);
      return;
   }
   if (update <= 0) {
      printf("Illegal update value %g, changed to 0.01\n",update);
      update = 0.01;
   }
   if (update < 0.001) printf("Warning update parameter is very small, processing may be slow\n");

   //autorestrict the amount of data to analyze
   MemInfo_t minfo;
   gSystem->GetMemInfo(&minfo);
   Int_t nfree = minfo.fMemTotal - minfo.fMemUsed;  //in Mbytes
   printf("TMemStat::Show info: you are running on a machine with %d free MBytes of memory\n",nfree);
   Long64_t nfreebytes = 200000*Long64_t(nfree); //use only 20% of the memory available
   if (fgAddressN <=0) fgAddressN = nfreebytes;
   Long64_t nentries = fgT->GetEntries();
   if (fgEntryN > 0 && nentries > fgEntryN) nentries = fgEntryN;
   if (2*8*nentries > 4*nfreebytes) {
      nentries = 4*nfreebytes/16;
      printf("not enough memory, restricting analysis to %lld entries\n",nentries);
   }
   fgT->SetEstimate(nentries);
   Long64_t nsel = fgT->Draw("pos","pos>0","goff",nentries);
   fgV1 = fgT->GetV1();
   Long64_t ivmin = (Long64_t)TMath::MinElement(nsel,fgV1);
   Long64_t ivmax = (Long64_t)TMath::MaxElement(nsel,fgV1);
   if (ivmax-ivmin > fgAddressN) ivmax = ivmin+fgAddressN;
   printf("TMemStatShow::Show will analyze only %lld bytes in its first pass\n",ivmax);


   //initialize statics
   fgTip1 = 0;
   fgTip2 = 0;
   fgBtidlist = 0;

   Long64_t ne = nfreebytes/32LL;
   if (ne < nentries) nentries = ne;
   fgT->SetEstimate(nentries+10);
   printf("sel: ivmin=%lld, ivmax=%lld, nentries=%lld\n",ivmin,ivmax,nentries);
   nsel = fgT->Draw("pos:nbytes:time:btid",
      TString::Format("pos>%g && pos<%g",Double_t(ivmin),Double_t(ivmax)),
      "goff",nentries,fgEntryFirst);

   //now we compute the best binning for the histogram
   Int_t nbytes;
   Double_t pos;
   fgV1 = fgT->GetV1();
   fgV2 = fgT->GetV2();
   fgV3 = fgT->GetV3();
   fgV4 = fgT->GetV4();
   ivmin = (Long64_t)TMath::MinElement(nsel,fgV1);
   ivmax = (Long64_t)TMath::MaxElement(nsel,fgV1);
   Long64_t bw = 1000;
   Double_t dvv = (Double_t(ivmax) - Double_t(ivmin))/Double_t(bw);
   Long64_t nbins = Long64_t(dvv);
   ivmin = ivmin -ivmin%bw;
   ivmax = ivmin+bw*nbins;
   Long64_t nvm = Long64_t(ivmax-ivmin+1);
   printf("==>The data Tree contains %lld entries with addresses in range[%lld,%lld]\n",nsel,ivmin,ivmax);
   //ne = (1000000*nfree-nvm*12)/32;
   ne = 1000000LL*nfree/32LL;
   if (ne < 0) return;
   if (ne < nentries) {
      //we take only the first side of the allocations
      //we are mostly interested by the small allocations, so we select
      //only values in the first gigabyte
      nsel = fgT->Draw("pos:nbytes:time:btid",
         TString::Format("pos>=%g && pos<%g",Double_t(ivmin),Double_t(ivmax)),"goff",ne,fgEntryFirst);
      fgV1 = fgT->GetV1();
      fgV2 = fgT->GetV2();
      fgV3 = fgT->GetV3();
      fgV4 = fgT->GetV4();
      ivmin = (Long64_t)TMath::MinElement(nsel,fgV1);
      ivmax = (Long64_t)TMath::MaxElement(nsel,fgV1);
      bw = 10000;
      dvv = (Double_t(ivmax) - Double_t(ivmin))/Double_t(bw);
      nbins = Long64_t(dvv+0.5);
      ivmin = ivmin -ivmin%bw;
      ivmax = ivmin+bw*nbins;
      printf("==>Address range or/and Entry range is too large\n");
      printf("==>restricting the analysis range to [%lld,%lld] and %lld entries\n",ivmin,ivmax,ne);
      printf("==>you can restrict the address range with TMemStatShow::SetAddressRange\n");
      printf("==>you can restrict the entries range with TMemStatShow::SetEntryRange\n");
   }
   update *= 0.0001*fgV3[nsel-1]; //convert time per cent in seconds
   nvm = Long64_t(ivmax-ivmin);
   Long64_t *nbold = new Long64_t[nvm];
   Int_t *ientry  = new Int_t[nvm];
   if (!nbold || !ientry) {
      printf("you do not have enough memory to run, %lld bytes needed\n",12*nvm);
      return;
   }
   memset(nbold,0,nvm*8);
   memset(ientry,0,nvm*4);
   Double_t dv = (ivmax-ivmin)/nbins;
   TH1D *h = new TH1D("h",Form("%s;pos;per cent of pages used",fname),nbins,ivmin,ivmax);
   fgH = h;
   TAxis *axis = h->GetXaxis();
   gStyle->SetOptStat("ie");
   h->SetFillColor(kRed);
   h->SetMinimum(0);
   h->SetMaximum(100);
   fgHalloc = new TH1D("fgHalloc",Form("%s;pos;number of mallocs",fname),nbins,ivmin,ivmax);
   fgHfree  = new TH1D("fgHfree", Form("%s;pos;number of frees",fname),nbins,ivmin,ivmax);
   fgHdiff = new TH1I("fgHdiff","",1000,0,1e5);
   //open a canvas and draw the empty histogram
   fgC1 = new TCanvas("fgC1","c1",1200,600);
   fgC1->SetFrameFillColor(kYellow-3);
   fgC1->SetGridx();
   fgC1->SetGridy();
   h->Draw();
   //create a TPaveText to show the summary results
   TPaveText *pvt = new TPaveText(.5,.9,.75,.99,"brNDC");
   pvt->Draw();
   //create a TPaveLabel to show the time
   TPaveLabel *ptime = new TPaveLabel(.905,.7,.995,.76,"time","brNDC");
   ptime->SetFillColor(kYellow-3);
   ptime->Draw();
   //draw producer identifier
   TNamed *named = (TNamed*)fgT->GetUserInfo()->FindObject("SysInfo");
   TText tmachine;
   tmachine.SetTextSize(0.02);
   tmachine.SetNDC();
   if (named) tmachine.DrawText(0.01,0.01,named->GetTitle());

   //start loop on selected rows
   Int_t bin,nb=0,j;
   Long64_t ipos;
   Double_t dbin,rest,time;
   Double_t updateLast = 0;
   Int_t nleaks = 0;
   Int_t i;
   for (i=0;i<nsel;i++) {
      pos    = fgV1[i];
      ipos = (Long64_t)(pos-ivmin);
      nbytes = (Int_t)fgV2[i];
      time = 0.0001*fgV3[i];
      bin = axis->FindBin(pos);
      if (bin<1 || bin>nbins) continue;
      dbin = axis->GetBinUpEdge(bin)-pos;
      if (nbytes > 0) {
         ientry[ipos] = i;
         fgHalloc->Fill(pos);
         if (dbin > nbytes) dbin = nbytes;
         //fill bytes in the first page
         h->AddBinContent(bin,100*dbin/dv);
         //fill bytes in full following pages
         nb = Int_t((nbytes-dbin)/dv);
         if (bin+nb >nbins) nb = nbins-bin;
         for (j=1;j<=nb;j++) h->AddBinContent(bin+j,100);
         //fill the bytes remaining in last page
         rest = nbytes-nb*dv-dbin;
         if (rest > 0) h->AddBinContent(bin+nb+1,100*rest/dv);
         //we save nbytes at pos. This info will be used when we free this slot
         //if (nbold[ipos] > 0) printf("reallocating %d bytes (was %lld) at %lld, entry=%d\n",nbytes,nbold[ipos],ipos,i);
         if (nbold[ipos] == 0) {
            nleaks++;
            //save the Tree entry number where we made this allocation
            ientry[ipos] = i;
         }
         nbold[ipos] = nbytes;
      } else {
         fgHfree->Fill(pos);
         nbytes = nbold[ipos];
         if (bin+nb >nbins) nb = nbins-bin;
         nbold[ipos] = 0; nleaks--;
         fgHdiff->Fill(i-ientry[ipos]);
         if (nbytes <= 0) continue;
         //fill bytes free in the first page
         if (dbin > nbytes) dbin = nbytes;
         h->AddBinContent(bin,-100*dbin/dv);
         //fill bytes free in full following pages
         nb = Int_t((nbytes-dbin)/dv);
         if (bin+nb >nbins) nb = nbins-bin;
         for (j=1;j<=nb;j++) h->AddBinContent(bin+j,-100);
         //fill the bytes free in  in last page
         rest = nbytes-nb*dv-dbin;
         if (rest > 0) h->AddBinContent(bin+nb+1,-100*rest/dv);

      }
      if (time -updateLast > update) {
         //update canvas at regular intervals
         updateLast = time;
         h->SetEntries(i);
         fgC1->Modified();
         pvt->GetListOfLines()->Delete();
         Double_t mbytes = 0;
         Int_t nonEmpty = 0;
         Double_t w;
         for (Int_t k=1;k<nbins;k++) {
            w = h->GetBinContent(k);
            if (w > 0) {
               nonEmpty++;
               mbytes += 0.01*w*dv;
            }
         }
         Double_t occupancy = mbytes/(nonEmpty*0.01*dv);
         pvt->AddText(Form("memory used = %g Mbytes",mbytes*1e-6));
         pvt->AddText(Form("page occupancy = %f per cent",occupancy));
         pvt->AddText("(for non empty pages only)");
         ptime->SetLabel(Form("%g sec",time));

         fgC1->Update();
         gSystem->ProcessEvents();
      }
   }
   h->SetEntries(nsel);
   if (nleaks < 0) nleaks=0;
   Int_t nlmax = nleaks;
   nleaks += 1000;
   Int_t *lindex  = new Int_t[nleaks];
   Int_t *entry   = new Int_t[nleaks];
   Int_t *ileaks  = new Int_t[nleaks];

   nleaks =0;
   for (Int_t ii=0;ii<nvm;ii++) {
      if (nbold[ii] > 0) {
         ileaks[nleaks] = (Int_t)nbold[ii];
         entry[nleaks]  = ientry[ii];
         nleaks++;
         if (nleaks > nlmax) break;
      }
   }
   TMath::Sort(nleaks,ileaks,lindex);
   fgHentry = new TH1I("fgHentry","leak entry index",nleaks,0,nleaks);
   fgHleaks = new TH1I("fgHleaks","leaks;leak number;nbytes in leak",nleaks,0,nleaks);
   for (Int_t k=0;k<nleaks;k++) {
      Int_t kk = lindex[k];
      i = entry[kk];
      fgHentry->SetBinContent(k+1,i);
      fgHleaks->SetBinContent(k+1,ileaks[kk]);
   }
   delete [] ileaks;
   delete [] entry;
   delete [] lindex;
   delete [] nbold;
   delete [] ientry;
   fgHentry->SetEntries(nleaks);
   fgHleaks->SetEntries(nleaks);


   //construct the first tooltip
   fgC1->Modified();
   fgC1->Update();
   TRootCanvas *rc1 = (TRootCanvas *)fgC1->GetCanvasImp();
   TGMainFrame *frm1 = dynamic_cast<TGMainFrame *>(rc1);
   // create the tooltip with a timeout of 250 ms
   if (!fgTip1) fgTip1 = new TGToolTip(gClient->GetDefaultRoot(), frm1, "", 250);
   fgC1->Connect("ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
                "TMemStatShow", 0, "EventInfo1(Int_t, Int_t, Int_t, TObject*)");
   if (nbigleaks <= 0) return;

   //---------------------------------------------------------------------------
   //open a second canvas and draw the histogram with leaks in decreasing order
   fgC2 = new TCanvas("fgC2","c2",1200,600);
   fgC2->SetFrameFillColor(kCyan-6);
   fgC2->SetGridx();
   fgC2->SetGridy();
   fgC2->SetLogy();
   fgHleaks->SetFillColor(kRed-3);
   if (nleaks > 1000) fgHleaks->GetXaxis()->SetRange(1,1000);
   fgHleaks->Draw();
   //draw producer identifier
   if (named) tmachine.DrawText(0.01,0.01,named->GetTitle());

   //construct the second tooltip
   TRootCanvas *rc2 = (TRootCanvas *)fgC2->GetCanvasImp();
   TGMainFrame *frm2 = dynamic_cast<TGMainFrame *>(rc2);
   // create the tooltip with a timeout of 250 ms
   if (!fgTip2) fgTip2 = new TGToolTip(gClient->GetDefaultRoot(), frm2, "", 250);
   fgC2->Connect("ProcessedEvent(Int_t, Int_t, Int_t, TObject*)",
               "TMemStatShow", 0, "EventInfo2(Int_t, Int_t, Int_t, TObject*)");

   //---------------------------------------------------------------------------
   //open a third canvas and draw the histogram with the nbigleaks largest leaks
   fgC3 = new TCanvas("fgC3","c3",1200,600);
   fgC3->SetFrameFillColor(kCyan-6);
   fgC3->SetGridx();
   fgC3->SetGridy();
   fgC3->SetLogx();
   fgC3->SetLeftMargin(0.05);
   fgC3->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++) {
      TString btstring = "";
      TMemStatShow::FillBTString(l,1,btstring);
      htotleaks->Fill(btstring.Data()+2,fgHleaks->GetBinContent(l));
   }
   Double_t tsize = 0.03;
   if (nbigleaks > 30) tsize = 0.02;
   htotleaks->LabelsOption(">");
   htotleaks->GetXaxis()->SetRange(1,nbigleaks);
   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*fgC3->GetLeftMargin();
   Double_t xr2 = 1.04*fgC3->GetLeftMargin();
   Double_t ytop = 1-fgC3->GetTopMargin();
   Double_t ylow = fgC3->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 (nchlabel > 0) {
            if (!strncmp(btstring.Data()+2,label,nchlabel)) nl++;
         } else {
            if (btstring.Length() == 0) nl++;
         }
      }
      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-fgC3->GetRightMargin(),0.5*ylow,"nbytes");
   //draw producer identifier
   if (named) tmachine.DrawText(0.01,0.01,named->GetTitle());

}

//______________________________________________________________________
void TMemStatShow::EventInfo1(Int_t event, Int_t px, Int_t , TObject *selected)
{
   // static: draw the tooltip showing the backtrace for the allocatios histogram
   if (!fgTip1) return;
   fgTip1->Hide();
   if (event == kMouseLeave)
      return;
   Double_t xpx  = fgC1->AbsPixeltoX(px);
   Double_t xpx1 = fgC1->AbsPixeltoX(px+1);
   Int_t bin  = fgH->GetXaxis()->FindBin(xpx);
   Int_t bin1 = fgH->GetXaxis()->FindBin(xpx1);
   //to take into account consecutive bins on the same pixel
   while (bin <= bin1) {
      if (fgH->GetBinContent(bin) > 0) break;
      bin++;
   }
   if (fgH->GetBinContent(bin) <= 0) return;
   if (bin <=0 || bin > fgH->GetXaxis()->GetNbins()) return;
   Double_t posmin = fgH->GetXaxis()->GetBinLowEdge(bin);
   Double_t posmax = fgH->GetXaxis()->GetBinUpEdge(bin);
   Int_t nsel   = (Int_t)fgT->GetSelectedRows();
   Int_t entry  = 0;
   Int_t nhits  = 0;
   Int_t nbytes = 0;
   //search for all allocations in this bin and select last one only
   for (Int_t i=0;i<nsel;i++) {
      if (fgV2[i] < 0) continue;
      if (fgV1[i] < posmax && fgV1[i]+fgV2[i] >posmin) {
         entry = i;
         nbytes = (Int_t)fgV2[i];
         nhits++;
      }
   }
   if (!nhits) return;

   Double_t time = 0.0001*fgV3[entry];
   TString ttip;
   TMemStatShow::FillBTString(entry,0,ttip);

   if (selected) {
      TString form1 = TString::Format("  Alloc(%d) at %lld of %d bytes, time=%gseconds\n\n",nhits,Long64_t(fgV1[entry]),nbytes,time);
      fgTip1->SetText(TString::Format("%s%s",form1.Data(),ttip.Data() ));
      fgTip1->SetPosition(px+15, 100);
      fgTip1->Reset();
   }
}

//______________________________________________________________________
void TMemStatShow::EventInfo2(Int_t event, Int_t px, Int_t , TObject *selected)
{
   // static: draw the tooltip showing the backtrace for the histogram of leaks
   if (!fgTip2) return;
   fgTip2->Hide();
   if (event == kMouseLeave)
      return;
   Double_t xpx  = fgC2->AbsPixeltoX(px);
   Int_t bin = fgHleaks->GetXaxis()->FindBin(xpx);
   if (bin <=0 || bin > fgHleaks->GetXaxis()->GetNbins()) return;
   Int_t nbytes  = (Int_t)fgHleaks->GetBinContent(bin);
   Int_t entry   = (Int_t)fgHentry->GetBinContent(bin);
   Double_t time = 0.0001*fgV3[entry];
   TString ttip;
   TMemStatShow::FillBTString(entry,0,ttip);

   if (selected) {
      TString form1 = TString::Format("  Leak number=%d, leaking %d bytes at entry=%d    time=%gseconds\n\n",bin,nbytes,entry,time);
      fgTip2->SetText(TString::Format("%s%s",form1.Data(),ttip.Data() ));
      fgTip2->SetPosition(px+15, 100);
      fgTip2->Reset();
   }
}

//______________________________________________________________________
void TMemStatShow::FillBTString(Int_t entry,Int_t mode,TString &btstring)
{
   // static: fill btstring with the traceback corresponding to entry in T
   //          btstring must be initialized in calling function

   Int_t btid   = (Int_t)fgV4[entry];
   TH1I *hbtids = (TH1I*)fgT->GetUserInfo()->FindObject("btids");
   if (!hbtids) return;
   if (!fgBtidlist) fgBtidlist = (TObjArray*)fgT->GetUserInfo()->FindObject("FAddrsList");
   if (!fgBtidlist) fgBtidlist = (TObjArray*)gFile->Get("FAddrsList"); //old memstat files
   if (!fgBtidlist) return;
   Int_t nbt = (Int_t)hbtids->GetBinContent(btid-1);
   for (Int_t i=0;i<nbt;i++) {
      Int_t j = (Int_t)hbtids->GetBinContent(btid+i);
      TNamed *nm = (TNamed*)fgBtidlist->At(j);
      if (nm==0) break;
      char *title = (char*)nm->GetTitle();
      Int_t nch = strlen(title);
      if (nch < 10) continue;
      if (strstr(title,"malloc")) continue;
      if (strstr(title,"memstat")) continue;
      if (strstr(title,"TMemStatHook")) continue;
      char *bar = strchr(title+5,'|');
      if (!bar) bar = title;

      if (strstr(bar,"operator new")) continue;
      if (strstr(bar,"libMemStat")) continue;
      if (strstr(bar,"G__Exception")) continue;
      if (mode) {
         btstring += TString::Format("%s ",bar);
         if (btstring.Length() > 80) return;
      } else {
         btstring += TString::Format("%2d %s\n",i,bar+1);
      }
   }
}
 TMemStatShow.cxx:1
 TMemStatShow.cxx:2
 TMemStatShow.cxx:3
 TMemStatShow.cxx:4
 TMemStatShow.cxx:5
 TMemStatShow.cxx:6
 TMemStatShow.cxx:7
 TMemStatShow.cxx:8
 TMemStatShow.cxx:9
 TMemStatShow.cxx:10
 TMemStatShow.cxx:11
 TMemStatShow.cxx:12
 TMemStatShow.cxx:13
 TMemStatShow.cxx:14
 TMemStatShow.cxx:15
 TMemStatShow.cxx:16
 TMemStatShow.cxx:17
 TMemStatShow.cxx:18
 TMemStatShow.cxx:19
 TMemStatShow.cxx:20
 TMemStatShow.cxx:21
 TMemStatShow.cxx:22
 TMemStatShow.cxx:23
 TMemStatShow.cxx:24
 TMemStatShow.cxx:25
 TMemStatShow.cxx:26
 TMemStatShow.cxx:27
 TMemStatShow.cxx:28
 TMemStatShow.cxx:29
 TMemStatShow.cxx:30
 TMemStatShow.cxx:31
 TMemStatShow.cxx:32
 TMemStatShow.cxx:33
 TMemStatShow.cxx:34
 TMemStatShow.cxx:35
 TMemStatShow.cxx:36
 TMemStatShow.cxx:37
 TMemStatShow.cxx:38
 TMemStatShow.cxx:39
 TMemStatShow.cxx:40
 TMemStatShow.cxx:41
 TMemStatShow.cxx:42
 TMemStatShow.cxx:43
 TMemStatShow.cxx:44
 TMemStatShow.cxx:45
 TMemStatShow.cxx:46
 TMemStatShow.cxx:47
 TMemStatShow.cxx:48
 TMemStatShow.cxx:49
 TMemStatShow.cxx:50
 TMemStatShow.cxx:51
 TMemStatShow.cxx:52
 TMemStatShow.cxx:53
 TMemStatShow.cxx:54
 TMemStatShow.cxx:55
 TMemStatShow.cxx:56
 TMemStatShow.cxx:57
 TMemStatShow.cxx:58
 TMemStatShow.cxx:59
 TMemStatShow.cxx:60
 TMemStatShow.cxx:61
 TMemStatShow.cxx:62
 TMemStatShow.cxx:63
 TMemStatShow.cxx:64
 TMemStatShow.cxx:65
 TMemStatShow.cxx:66
 TMemStatShow.cxx:67
 TMemStatShow.cxx:68
 TMemStatShow.cxx:69
 TMemStatShow.cxx:70
 TMemStatShow.cxx:71
 TMemStatShow.cxx:72
 TMemStatShow.cxx:73
 TMemStatShow.cxx:74
 TMemStatShow.cxx:75
 TMemStatShow.cxx:76
 TMemStatShow.cxx:77
 TMemStatShow.cxx:78
 TMemStatShow.cxx:79
 TMemStatShow.cxx:80
 TMemStatShow.cxx:81
 TMemStatShow.cxx:82
 TMemStatShow.cxx:83
 TMemStatShow.cxx:84
 TMemStatShow.cxx:85
 TMemStatShow.cxx:86
 TMemStatShow.cxx:87
 TMemStatShow.cxx:88
 TMemStatShow.cxx:89
 TMemStatShow.cxx:90
 TMemStatShow.cxx:91
 TMemStatShow.cxx:92
 TMemStatShow.cxx:93
 TMemStatShow.cxx:94
 TMemStatShow.cxx:95
 TMemStatShow.cxx:96
 TMemStatShow.cxx:97
 TMemStatShow.cxx:98
 TMemStatShow.cxx:99
 TMemStatShow.cxx:100
 TMemStatShow.cxx:101
 TMemStatShow.cxx:102
 TMemStatShow.cxx:103
 TMemStatShow.cxx:104
 TMemStatShow.cxx:105
 TMemStatShow.cxx:106
 TMemStatShow.cxx:107
 TMemStatShow.cxx:108
 TMemStatShow.cxx:109
 TMemStatShow.cxx:110
 TMemStatShow.cxx:111
 TMemStatShow.cxx:112
 TMemStatShow.cxx:113
 TMemStatShow.cxx:114
 TMemStatShow.cxx:115
 TMemStatShow.cxx:116
 TMemStatShow.cxx:117
 TMemStatShow.cxx:118
 TMemStatShow.cxx:119
 TMemStatShow.cxx:120
 TMemStatShow.cxx:121
 TMemStatShow.cxx:122
 TMemStatShow.cxx:123
 TMemStatShow.cxx:124
 TMemStatShow.cxx:125
 TMemStatShow.cxx:126
 TMemStatShow.cxx:127
 TMemStatShow.cxx:128
 TMemStatShow.cxx:129
 TMemStatShow.cxx:130
 TMemStatShow.cxx:131
 TMemStatShow.cxx:132
 TMemStatShow.cxx:133
 TMemStatShow.cxx:134
 TMemStatShow.cxx:135
 TMemStatShow.cxx:136
 TMemStatShow.cxx:137
 TMemStatShow.cxx:138
 TMemStatShow.cxx:139
 TMemStatShow.cxx:140
 TMemStatShow.cxx:141
 TMemStatShow.cxx:142
 TMemStatShow.cxx:143
 TMemStatShow.cxx:144
 TMemStatShow.cxx:145
 TMemStatShow.cxx:146
 TMemStatShow.cxx:147
 TMemStatShow.cxx:148
 TMemStatShow.cxx:149
 TMemStatShow.cxx:150
 TMemStatShow.cxx:151
 TMemStatShow.cxx:152
 TMemStatShow.cxx:153
 TMemStatShow.cxx:154
 TMemStatShow.cxx:155
 TMemStatShow.cxx:156
 TMemStatShow.cxx:157
 TMemStatShow.cxx:158
 TMemStatShow.cxx:159
 TMemStatShow.cxx:160
 TMemStatShow.cxx:161
 TMemStatShow.cxx:162
 TMemStatShow.cxx:163
 TMemStatShow.cxx:164
 TMemStatShow.cxx:165
 TMemStatShow.cxx:166
 TMemStatShow.cxx:167
 TMemStatShow.cxx:168
 TMemStatShow.cxx:169
 TMemStatShow.cxx:170
 TMemStatShow.cxx:171
 TMemStatShow.cxx:172
 TMemStatShow.cxx:173
 TMemStatShow.cxx:174
 TMemStatShow.cxx:175
 TMemStatShow.cxx:176
 TMemStatShow.cxx:177
 TMemStatShow.cxx:178
 TMemStatShow.cxx:179
 TMemStatShow.cxx:180
 TMemStatShow.cxx:181
 TMemStatShow.cxx:182
 TMemStatShow.cxx:183
 TMemStatShow.cxx:184
 TMemStatShow.cxx:185
 TMemStatShow.cxx:186
 TMemStatShow.cxx:187
 TMemStatShow.cxx:188
 TMemStatShow.cxx:189
 TMemStatShow.cxx:190
 TMemStatShow.cxx:191
 TMemStatShow.cxx:192
 TMemStatShow.cxx:193
 TMemStatShow.cxx:194
 TMemStatShow.cxx:195
 TMemStatShow.cxx:196
 TMemStatShow.cxx:197
 TMemStatShow.cxx:198
 TMemStatShow.cxx:199
 TMemStatShow.cxx:200
 TMemStatShow.cxx:201
 TMemStatShow.cxx:202
 TMemStatShow.cxx:203
 TMemStatShow.cxx:204
 TMemStatShow.cxx:205
 TMemStatShow.cxx:206
 TMemStatShow.cxx:207
 TMemStatShow.cxx:208
 TMemStatShow.cxx:209
 TMemStatShow.cxx:210
 TMemStatShow.cxx:211
 TMemStatShow.cxx:212
 TMemStatShow.cxx:213
 TMemStatShow.cxx:214
 TMemStatShow.cxx:215
 TMemStatShow.cxx:216
 TMemStatShow.cxx:217
 TMemStatShow.cxx:218
 TMemStatShow.cxx:219
 TMemStatShow.cxx:220
 TMemStatShow.cxx:221
 TMemStatShow.cxx:222
 TMemStatShow.cxx:223
 TMemStatShow.cxx:224
 TMemStatShow.cxx:225
 TMemStatShow.cxx:226
 TMemStatShow.cxx:227
 TMemStatShow.cxx:228
 TMemStatShow.cxx:229
 TMemStatShow.cxx:230
 TMemStatShow.cxx:231
 TMemStatShow.cxx:232
 TMemStatShow.cxx:233
 TMemStatShow.cxx:234
 TMemStatShow.cxx:235
 TMemStatShow.cxx:236
 TMemStatShow.cxx:237
 TMemStatShow.cxx:238
 TMemStatShow.cxx:239
 TMemStatShow.cxx:240
 TMemStatShow.cxx:241
 TMemStatShow.cxx:242
 TMemStatShow.cxx:243
 TMemStatShow.cxx:244
 TMemStatShow.cxx:245
 TMemStatShow.cxx:246
 TMemStatShow.cxx:247
 TMemStatShow.cxx:248
 TMemStatShow.cxx:249
 TMemStatShow.cxx:250
 TMemStatShow.cxx:251
 TMemStatShow.cxx:252
 TMemStatShow.cxx:253
 TMemStatShow.cxx:254
 TMemStatShow.cxx:255
 TMemStatShow.cxx:256
 TMemStatShow.cxx:257
 TMemStatShow.cxx:258
 TMemStatShow.cxx:259
 TMemStatShow.cxx:260
 TMemStatShow.cxx:261
 TMemStatShow.cxx:262
 TMemStatShow.cxx:263
 TMemStatShow.cxx:264
 TMemStatShow.cxx:265
 TMemStatShow.cxx:266
 TMemStatShow.cxx:267
 TMemStatShow.cxx:268
 TMemStatShow.cxx:269
 TMemStatShow.cxx:270
 TMemStatShow.cxx:271
 TMemStatShow.cxx:272
 TMemStatShow.cxx:273
 TMemStatShow.cxx:274
 TMemStatShow.cxx:275
 TMemStatShow.cxx:276
 TMemStatShow.cxx:277
 TMemStatShow.cxx:278
 TMemStatShow.cxx:279
 TMemStatShow.cxx:280
 TMemStatShow.cxx:281
 TMemStatShow.cxx:282
 TMemStatShow.cxx:283
 TMemStatShow.cxx:284
 TMemStatShow.cxx:285
 TMemStatShow.cxx:286
 TMemStatShow.cxx:287
 TMemStatShow.cxx:288
 TMemStatShow.cxx:289
 TMemStatShow.cxx:290
 TMemStatShow.cxx:291
 TMemStatShow.cxx:292
 TMemStatShow.cxx:293
 TMemStatShow.cxx:294
 TMemStatShow.cxx:295
 TMemStatShow.cxx:296
 TMemStatShow.cxx:297
 TMemStatShow.cxx:298
 TMemStatShow.cxx:299
 TMemStatShow.cxx:300
 TMemStatShow.cxx:301
 TMemStatShow.cxx:302
 TMemStatShow.cxx:303
 TMemStatShow.cxx:304
 TMemStatShow.cxx:305
 TMemStatShow.cxx:306
 TMemStatShow.cxx:307
 TMemStatShow.cxx:308
 TMemStatShow.cxx:309
 TMemStatShow.cxx:310
 TMemStatShow.cxx:311
 TMemStatShow.cxx:312
 TMemStatShow.cxx:313
 TMemStatShow.cxx:314
 TMemStatShow.cxx:315
 TMemStatShow.cxx:316
 TMemStatShow.cxx:317
 TMemStatShow.cxx:318
 TMemStatShow.cxx:319
 TMemStatShow.cxx:320
 TMemStatShow.cxx:321
 TMemStatShow.cxx:322
 TMemStatShow.cxx:323
 TMemStatShow.cxx:324
 TMemStatShow.cxx:325
 TMemStatShow.cxx:326
 TMemStatShow.cxx:327
 TMemStatShow.cxx:328
 TMemStatShow.cxx:329
 TMemStatShow.cxx:330
 TMemStatShow.cxx:331
 TMemStatShow.cxx:332
 TMemStatShow.cxx:333
 TMemStatShow.cxx:334
 TMemStatShow.cxx:335
 TMemStatShow.cxx:336
 TMemStatShow.cxx:337
 TMemStatShow.cxx:338
 TMemStatShow.cxx:339
 TMemStatShow.cxx:340
 TMemStatShow.cxx:341
 TMemStatShow.cxx:342
 TMemStatShow.cxx:343
 TMemStatShow.cxx:344
 TMemStatShow.cxx:345
 TMemStatShow.cxx:346
 TMemStatShow.cxx:347
 TMemStatShow.cxx:348
 TMemStatShow.cxx:349
 TMemStatShow.cxx:350
 TMemStatShow.cxx:351
 TMemStatShow.cxx:352
 TMemStatShow.cxx:353
 TMemStatShow.cxx:354
 TMemStatShow.cxx:355
 TMemStatShow.cxx:356
 TMemStatShow.cxx:357
 TMemStatShow.cxx:358
 TMemStatShow.cxx:359
 TMemStatShow.cxx:360
 TMemStatShow.cxx:361
 TMemStatShow.cxx:362
 TMemStatShow.cxx:363
 TMemStatShow.cxx:364
 TMemStatShow.cxx:365
 TMemStatShow.cxx:366
 TMemStatShow.cxx:367
 TMemStatShow.cxx:368
 TMemStatShow.cxx:369
 TMemStatShow.cxx:370
 TMemStatShow.cxx:371
 TMemStatShow.cxx:372
 TMemStatShow.cxx:373
 TMemStatShow.cxx:374
 TMemStatShow.cxx:375
 TMemStatShow.cxx:376
 TMemStatShow.cxx:377
 TMemStatShow.cxx:378
 TMemStatShow.cxx:379
 TMemStatShow.cxx:380
 TMemStatShow.cxx:381
 TMemStatShow.cxx:382
 TMemStatShow.cxx:383
 TMemStatShow.cxx:384
 TMemStatShow.cxx:385
 TMemStatShow.cxx:386
 TMemStatShow.cxx:387
 TMemStatShow.cxx:388
 TMemStatShow.cxx:389
 TMemStatShow.cxx:390
 TMemStatShow.cxx:391
 TMemStatShow.cxx:392
 TMemStatShow.cxx:393
 TMemStatShow.cxx:394
 TMemStatShow.cxx:395
 TMemStatShow.cxx:396
 TMemStatShow.cxx:397
 TMemStatShow.cxx:398
 TMemStatShow.cxx:399
 TMemStatShow.cxx:400
 TMemStatShow.cxx:401
 TMemStatShow.cxx:402
 TMemStatShow.cxx:403
 TMemStatShow.cxx:404
 TMemStatShow.cxx:405
 TMemStatShow.cxx:406
 TMemStatShow.cxx:407
 TMemStatShow.cxx:408
 TMemStatShow.cxx:409
 TMemStatShow.cxx:410
 TMemStatShow.cxx:411
 TMemStatShow.cxx:412
 TMemStatShow.cxx:413
 TMemStatShow.cxx:414
 TMemStatShow.cxx:415
 TMemStatShow.cxx:416
 TMemStatShow.cxx:417
 TMemStatShow.cxx:418
 TMemStatShow.cxx:419
 TMemStatShow.cxx:420
 TMemStatShow.cxx:421
 TMemStatShow.cxx:422
 TMemStatShow.cxx:423
 TMemStatShow.cxx:424
 TMemStatShow.cxx:425
 TMemStatShow.cxx:426
 TMemStatShow.cxx:427
 TMemStatShow.cxx:428
 TMemStatShow.cxx:429
 TMemStatShow.cxx:430
 TMemStatShow.cxx:431
 TMemStatShow.cxx:432
 TMemStatShow.cxx:433
 TMemStatShow.cxx:434
 TMemStatShow.cxx:435
 TMemStatShow.cxx:436
 TMemStatShow.cxx:437
 TMemStatShow.cxx:438
 TMemStatShow.cxx:439
 TMemStatShow.cxx:440
 TMemStatShow.cxx:441
 TMemStatShow.cxx:442
 TMemStatShow.cxx:443
 TMemStatShow.cxx:444
 TMemStatShow.cxx:445
 TMemStatShow.cxx:446
 TMemStatShow.cxx:447
 TMemStatShow.cxx:448
 TMemStatShow.cxx:449
 TMemStatShow.cxx:450
 TMemStatShow.cxx:451
 TMemStatShow.cxx:452
 TMemStatShow.cxx:453
 TMemStatShow.cxx:454
 TMemStatShow.cxx:455
 TMemStatShow.cxx:456
 TMemStatShow.cxx:457
 TMemStatShow.cxx:458
 TMemStatShow.cxx:459
 TMemStatShow.cxx:460
 TMemStatShow.cxx:461
 TMemStatShow.cxx:462
 TMemStatShow.cxx:463
 TMemStatShow.cxx:464
 TMemStatShow.cxx:465
 TMemStatShow.cxx:466
 TMemStatShow.cxx:467
 TMemStatShow.cxx:468
 TMemStatShow.cxx:469
 TMemStatShow.cxx:470
 TMemStatShow.cxx:471
 TMemStatShow.cxx:472
 TMemStatShow.cxx:473
 TMemStatShow.cxx:474
 TMemStatShow.cxx:475
 TMemStatShow.cxx:476
 TMemStatShow.cxx:477
 TMemStatShow.cxx:478
 TMemStatShow.cxx:479
 TMemStatShow.cxx:480
 TMemStatShow.cxx:481
 TMemStatShow.cxx:482
 TMemStatShow.cxx:483
 TMemStatShow.cxx:484
 TMemStatShow.cxx:485
 TMemStatShow.cxx:486
 TMemStatShow.cxx:487
 TMemStatShow.cxx:488
 TMemStatShow.cxx:489
 TMemStatShow.cxx:490
 TMemStatShow.cxx:491
 TMemStatShow.cxx:492
 TMemStatShow.cxx:493
 TMemStatShow.cxx:494
 TMemStatShow.cxx:495
 TMemStatShow.cxx:496
 TMemStatShow.cxx:497
 TMemStatShow.cxx:498
 TMemStatShow.cxx:499
 TMemStatShow.cxx:500
 TMemStatShow.cxx:501
 TMemStatShow.cxx:502
 TMemStatShow.cxx:503
 TMemStatShow.cxx:504
 TMemStatShow.cxx:505
 TMemStatShow.cxx:506
 TMemStatShow.cxx:507
 TMemStatShow.cxx:508
 TMemStatShow.cxx:509
 TMemStatShow.cxx:510
 TMemStatShow.cxx:511
 TMemStatShow.cxx:512
 TMemStatShow.cxx:513
 TMemStatShow.cxx:514
 TMemStatShow.cxx:515
 TMemStatShow.cxx:516
 TMemStatShow.cxx:517
 TMemStatShow.cxx:518
 TMemStatShow.cxx:519
 TMemStatShow.cxx:520
 TMemStatShow.cxx:521
 TMemStatShow.cxx:522
 TMemStatShow.cxx:523
 TMemStatShow.cxx:524
 TMemStatShow.cxx:525
 TMemStatShow.cxx:526
 TMemStatShow.cxx:527
 TMemStatShow.cxx:528
 TMemStatShow.cxx:529
 TMemStatShow.cxx:530
 TMemStatShow.cxx:531
 TMemStatShow.cxx:532
 TMemStatShow.cxx:533
 TMemStatShow.cxx:534
 TMemStatShow.cxx:535
 TMemStatShow.cxx:536
 TMemStatShow.cxx:537
 TMemStatShow.cxx:538
 TMemStatShow.cxx:539
 TMemStatShow.cxx:540
 TMemStatShow.cxx:541
 TMemStatShow.cxx:542
 TMemStatShow.cxx:543
 TMemStatShow.cxx:544
 TMemStatShow.cxx:545
 TMemStatShow.cxx:546
 TMemStatShow.cxx:547
 TMemStatShow.cxx:548
 TMemStatShow.cxx:549
 TMemStatShow.cxx:550
 TMemStatShow.cxx:551
 TMemStatShow.cxx:552
 TMemStatShow.cxx:553
 TMemStatShow.cxx:554
 TMemStatShow.cxx:555
 TMemStatShow.cxx:556
 TMemStatShow.cxx:557
 TMemStatShow.cxx:558
 TMemStatShow.cxx:559
 TMemStatShow.cxx:560
 TMemStatShow.cxx:561
 TMemStatShow.cxx:562
 TMemStatShow.cxx:563
 TMemStatShow.cxx:564
 TMemStatShow.cxx:565
 TMemStatShow.cxx:566
 TMemStatShow.cxx:567
 TMemStatShow.cxx:568
 TMemStatShow.cxx:569
 TMemStatShow.cxx:570
 TMemStatShow.cxx:571
 TMemStatShow.cxx:572
 TMemStatShow.cxx:573
 TMemStatShow.cxx:574
 TMemStatShow.cxx:575
 TMemStatShow.cxx:576
 TMemStatShow.cxx:577
 TMemStatShow.cxx:578
 TMemStatShow.cxx:579
 TMemStatShow.cxx:580
 TMemStatShow.cxx:581
 TMemStatShow.cxx:582
 TMemStatShow.cxx:583
 TMemStatShow.cxx:584
 TMemStatShow.cxx:585
 TMemStatShow.cxx:586
 TMemStatShow.cxx:587
 TMemStatShow.cxx:588
 TMemStatShow.cxx:589
 TMemStatShow.cxx:590
 TMemStatShow.cxx:591
 TMemStatShow.cxx:592
 TMemStatShow.cxx:593
 TMemStatShow.cxx:594
 TMemStatShow.cxx:595
 TMemStatShow.cxx:596
 TMemStatShow.cxx:597
 TMemStatShow.cxx:598
 TMemStatShow.cxx:599
 TMemStatShow.cxx:600
 TMemStatShow.cxx:601
 TMemStatShow.cxx:602
 TMemStatShow.cxx:603
 TMemStatShow.cxx:604
 TMemStatShow.cxx:605
 TMemStatShow.cxx:606
 TMemStatShow.cxx:607
 TMemStatShow.cxx:608
 TMemStatShow.cxx:609
 TMemStatShow.cxx:610
 TMemStatShow.cxx:611
 TMemStatShow.cxx:612
 TMemStatShow.cxx:613
 TMemStatShow.cxx:614
 TMemStatShow.cxx:615
 TMemStatShow.cxx:616
 TMemStatShow.cxx:617
 TMemStatShow.cxx:618
 TMemStatShow.cxx:619
 TMemStatShow.cxx:620
 TMemStatShow.cxx:621
 TMemStatShow.cxx:622
 TMemStatShow.cxx:623
 TMemStatShow.cxx:624
 TMemStatShow.cxx:625
 TMemStatShow.cxx:626
 TMemStatShow.cxx:627
 TMemStatShow.cxx:628
 TMemStatShow.cxx:629
 TMemStatShow.cxx:630
 TMemStatShow.cxx:631
 TMemStatShow.cxx:632
 TMemStatShow.cxx:633
 TMemStatShow.cxx:634
 TMemStatShow.cxx:635
 TMemStatShow.cxx:636
 TMemStatShow.cxx:637
 TMemStatShow.cxx:638
 TMemStatShow.cxx:639
 TMemStatShow.cxx:640
 TMemStatShow.cxx:641