1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //_________________________________________________________________________
18 //Basic Memory Leak utility.
19 // You can use this tiny class to *see* if your program is leaking.
21 // AliMemoryWatcher memwatcher;
22 // some program loop on events here {
23 // if ( nevents % x == 0 )
25 // // take a sample every x events
26 // memwatcher.Watch(nevents);
29 // TFile f("out.root","RECREATE");
30 // memwatcher.Write();
32 // In the output root file you'll get 3 graphs representing
33 // the evolAliPHOSon, as a function of the number of events, of :
34 // - VSIZE is the virtual size (in KBytes) of your program, that is sort of
35 // the total memory used
36 // - RSSIZE is the resident size (in KBytes), that is, the part of your
37 // program which is really in physical memory.
38 // - TIME is an estimate of time per event (really it's the time elasped
39 // between two calls to watch method)
40 // WARNING: this is far from a bulletproof memory report (it's basically
41 // using UNIX command ps -h -p [PID] -o vsize,rssize to do its job).
42 // It has only been tested on Linux so far.
43 // But by fitting the VSIZE by a pol1 under ROOT, you'll see right away
44 // by how much your program is leaking.
45 //*-- Author: Laurent Aphecetche(SUBATECH)
54 // --- AliRoot header files ---
56 #include "AliMemoryWatcher.h"
57 // --- ROOT system ---
61 #include "TStopwatch.h"
64 ClassImp(AliMemoryWatcher)
66 //_____________________________________________________________________________
67 AliMemoryWatcher::AliMemoryWatcher(UInt_t maxsize) :
70 fPID(gSystem->GetPid()),
73 fX(new Int_t[fMAXSIZE]),
74 fVSIZE(new Int_t[fMAXSIZE]),
75 fRSSIZE(new Int_t[fMAXSIZE]),
76 fTIME(new Double_t[fMAXSIZE]),
83 sprintf(fCmd,"ps -h -p %d -o vsz,rss | grep -v VSZ",fPID);
86 //_____________________________________________________________________________
87 AliMemoryWatcher::AliMemoryWatcher(const AliMemoryWatcher& mw):
89 fUseMallinfo(mw.fUseMallinfo),
91 fMAXSIZE(mw.fMAXSIZE),
93 fX(new Int_t[fMAXSIZE]),
94 fVSIZE(new Int_t[fMAXSIZE]),
95 fRSSIZE(new Int_t[fMAXSIZE]),
96 fTIME(new Double_t[fMAXSIZE]),
101 strcpy(fCmd, mw.fCmd) ;
104 //_____________________________________________________________________________
105 AliMemoryWatcher::~AliMemoryWatcher()
114 //_____________________________________________________________________________
115 void AliMemoryWatcher::Watch(Int_t x)
117 // Sets the point where CPU parameters have to be monitored
118 if ( !fDisabled && fSize < fMAXSIZE ) {
121 fTimer = new TStopwatch;
125 if ( fUseMallinfo ) {
127 static struct mallinfo meminfo;
128 meminfo = mallinfo();
130 fVSIZE[fSize] = (meminfo.hblkhd + meminfo.uordblks) / 1024;
131 fRSSIZE[fSize] = meminfo.uordblks / 1024;
132 fTIME[fSize] = fTimer->CpuTime();
135 AliFatal("Please SetUseMallinfo to kFALSE on this system");
138 static Int_t vsize, rssize;
139 static FILE* pipe = 0;
140 pipe = popen(fCmd,"r");
143 fscanf(pipe,"%d %d",&vsize,&rssize);
146 fVSIZE[fSize] = vsize ;
147 fRSSIZE[fSize] = rssize ;
148 fTIME[fSize] = fTimer->CpuTime();
151 assert(pclose(pipe)!=-1);
157 AliError("I'm full !" ) ;
160 //_____________________________________________________________________________
162 AliMemoryWatcher::GraphVSIZE(void)
164 // Fills the graph with the virtual memory sized used
168 g = new TGraph(Size());
170 for (i=0; i < g->GetN(); i++ ) {
171 g->SetPoint(i,X(i),VSIZE(i));
176 //_____________________________________________________________________________
178 AliMemoryWatcher::GraphRSSIZE(void)
180 // Fills the graph with the real memory sized used
184 g = new TGraph(Size());
186 for (i=0; i < g->GetN(); i++ ) {
187 g->SetPoint(i,X(i),RSSIZE(i));
192 //_____________________________________________________________________________
194 AliMemoryWatcher::GraphTIME(void)
196 // Fills the raph with the used CPU time
200 g = new TGraph(Size());
202 for (i=0; i < g->GetN(); i++ ) {
203 g->SetPoint(i,X(i),TIME(i));
208 //_____________________________________________________________________________
210 AliMemoryWatcher::Frame(void) const
212 //creates the frame histo in which the graphs will be plotted
218 for (i=0; i < Size() ; i++ ) {
219 if ( X(i) < xmin ) xmin = X(i);
220 if ( X(i) > xmax ) xmax = X(i);
221 Double_t y = VSIZE(i)+RSSIZE(i);
222 if ( y > ymax ) ymax = y;
223 if ( VSIZE(i) < ymin ) ymin = VSIZE(i);
224 if ( RSSIZE(i) < ymin ) ymin = RSSIZE(i);
226 TH2F* h = new TH2F("frame","",10,xmin,xmax,10,ymin*0.8,ymax*1.2);
229 //_____________________________________________________________________________
231 AliMemoryWatcher::WriteToFile()
233 // Stores the graphs in a file
234 if ( GraphVSIZE() ) GraphVSIZE()->Write("VSIZE",TObject::kOverwrite);
235 if ( GraphRSSIZE() ) GraphRSSIZE() ->Write("RSSIZE",TObject::kOverwrite);
236 if ( GraphTIME() ) GraphTIME()->Write("TIME",TObject::kOverwrite);