]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliMemoryWatcher.cxx
Backward compatibility with Root v3-10-02 and v4-00-08
[u/mrichter/AliRoot.git] / STEER / AliMemoryWatcher.cxx
CommitLineData
d60522e4 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15/* $Id$ */
16//_________________________________________________________________________
00399209 17//Basic Memory Leak utility.
18// You can use this tiny class to *see* if your program is leaking.
19// Usage:
ac8cd48d 20// AliMemoryWatcher memwatcher;
00399209 21// some program loop on events here {
22// if ( nevents % x == 0 )
23// {
24// // take a sample every x events
7c8a93e6 25// memwatcher.Watch(nevents);
00399209 26// }
27// }
28// TFile f("out.root","RECREATE");
7c8a93e6 29// memwatcher.Write();
00399209 30// f.Close();
31// In the output root file you'll get 3 graphs representing
32// the evolAliPHOSon, as a function of the number of events, of :
33// - VSIZE is the virtual size (in KBytes) of your program, that is sort of
34// the total memory used
35// - RSSIZE is the resident size (in KBytes), that is, the part of your
36// program which is really in physical memory.
37// - TIME is an estimate of time per event (really it's the time elasped
38// between two calls to watch method)
39// WARNING: this is far from a bulletproof memory report (it's basically
40// using UNIX command ps -h -p [PID] -o vsize,rssize to do its job).
41// It has only been tested on Linux so far.
42// But by fitting the VSIZE by a pol1 under ROOT, you'll see right away
43// by how much your program is leaking.
d60522e4 44//*-- Author: Laurent Aphecetche(SUBATECH)
d60522e4 45// --- std system ---
b01af8c2 46class assert ;
7406fd3c 47#include <malloc.h>
d60522e4 48// --- AliRoot header files ---
ac8cd48d 49#include "AliMemoryWatcher.h"
d60522e4 50// --- ROOT system ---
51#include "TSystem.h"
52#include "TGraph.h"
53#include "TH2.h"
54#include "TStopwatch.h"
7c8a93e6 55#include "TError.h"
dfe7f75b 56
ac8cd48d 57ClassImp(AliMemoryWatcher)
dfe7f75b 58
d60522e4 59//_____________________________________________________________________________
ac8cd48d 60AliMemoryWatcher::AliMemoryWatcher(UInt_t maxsize)
d60522e4 61{
b01af8c2 62 //ctor
d60522e4 63 fMAXSIZE=maxsize;
7406fd3c 64 fUseMallinfo = true;
d60522e4 65 fPID = gSystem->GetPid();
66 sprintf(fCmd,"ps -h -p %d -o vsize,rssize",fPID);
b01af8c2 67 fX = new Int_t[fMAXSIZE];
68 fVSIZE = new Int_t[fMAXSIZE];
69 fRSSIZE = new Int_t[fMAXSIZE];
70 fTIME = new Double_t[fMAXSIZE];
d60522e4 71 fSize=0;
72 fDisabled=false;
73 fTimer=0;
74}
d60522e4 75//_____________________________________________________________________________
d1898505 76AliMemoryWatcher::AliMemoryWatcher(const AliMemoryWatcher& mw):
77 TObject(mw)
00399209 78{
79 //copy ctor
80 fMAXSIZE = mw.fMAXSIZE ;
7406fd3c 81 fUseMallinfo = mw.fUseMallinfo;
00399209 82 fPID = mw.fPID ;
83 strcpy(fCmd, mw.fCmd) ;
84 fX = new Int_t[fMAXSIZE];
85 fVSIZE = new Int_t[fMAXSIZE];
86 fRSSIZE = new Int_t[fMAXSIZE];
87 fTIME = new Double_t[fMAXSIZE];
88 fSize=0;
89 fDisabled=false;
90 fTimer=0;
91}
92//_____________________________________________________________________________
ac8cd48d 93AliMemoryWatcher::~AliMemoryWatcher()
d60522e4 94{
2a6e66b9 95 // dtor
d60522e4 96 delete[] fVSIZE;
97 delete[] fRSSIZE;
98 delete[] fX;
99 delete[] fTIME;
100 delete fTimer;
101}
d60522e4 102//_____________________________________________________________________________
ac8cd48d 103void AliMemoryWatcher::Watch(Int_t x)
d60522e4 104{
b01af8c2 105 // Sets the point where CPU parameters have to be monitored
d60522e4 106 if ( !fDisabled && fSize < fMAXSIZE ) {
d60522e4 107 if ( fSize==0 ) {
108 assert(fTimer==0);
109 fTimer = new TStopwatch;
110 fTimer->Start(true);
111 fTimer->Stop();
112 }
7406fd3c 113 if ( fUseMallinfo ) {
1844c927 114#ifdef __linux
7406fd3c 115 static struct mallinfo meminfo;
116 meminfo = mallinfo();
d60522e4 117 fX[fSize] = x ;
7406fd3c 118 fVSIZE[fSize] = (meminfo.hblkhd + meminfo.uordblks) / 1024;
119 fRSSIZE[fSize] = meminfo.uordblks / 1024;
d60522e4 120 fTIME[fSize] = fTimer->CpuTime();
121 fSize++;
1844c927 122#else
123 ::Fatal("Watch","Please SetUseMallinfo to kFALSE on this system");
124#endif
7406fd3c 125 } else {
126 static Int_t vsize, rssize;
127 static FILE* pipe = 0;
128 pipe = popen(fCmd,"r");
129 if ( pipe ) {
130
131 fscanf(pipe,"%d %d",&vsize,&rssize);
132
133 fX[fSize] = x ;
134 fVSIZE[fSize] = vsize ;
135 fRSSIZE[fSize] = rssize ;
136 fTIME[fSize] = fTimer->CpuTime();
137 fSize++;
138 }
139 assert(pclose(pipe)!=-1);
d60522e4 140 }
d60522e4 141 fTimer->Start(true);
d60522e4 142 }
143 else {
144 fDisabled=true;
21cd0c07 145 Error("watch", "I'm full !" ) ;
d60522e4 146 }
147}
d60522e4 148//_____________________________________________________________________________
149TGraph*
ac8cd48d 150AliMemoryWatcher::GraphVSIZE(void)
d60522e4 151{
b01af8c2 152 // Fills the graph with the virtual memory sized used
d60522e4 153 TGraph* g = 0;
00399209 154 if ( Size() )
d60522e4 155 {
00399209 156 g = new TGraph(Size());
b01af8c2 157 Int_t i ;
158 for (i=0; i < g->GetN(); i++ ) {
d60522e4 159 g->SetPoint(i,X(i),VSIZE(i));
160 }
161 }
162 return g;
163}
d60522e4 164//_____________________________________________________________________________
165TGraph*
ac8cd48d 166AliMemoryWatcher::GraphRSSIZE(void)
d60522e4 167{
b01af8c2 168 // Fills the graph with the real memory sized used
d60522e4 169 TGraph* g = 0;
00399209 170 if ( Size() )
d60522e4 171 {
00399209 172 g = new TGraph(Size());
b01af8c2 173 Int_t i ;
174 for (i=0; i < g->GetN(); i++ ) {
d60522e4 175 g->SetPoint(i,X(i),RSSIZE(i));
176 }
177 }
178 return g;
179}
d60522e4 180//_____________________________________________________________________________
181TGraph*
ac8cd48d 182AliMemoryWatcher::GraphTIME(void)
d60522e4 183{
b01af8c2 184 // Fills the raph with the used CPU time
d60522e4 185 TGraph* g = 0;
00399209 186 if ( Size() )
d60522e4 187 {
00399209 188 g = new TGraph(Size());
b01af8c2 189 Int_t i ;
190 for (i=0; i < g->GetN(); i++ ) {
d60522e4 191 g->SetPoint(i,X(i),TIME(i));
192 }
193 }
194 return g;
195}
d60522e4 196//_____________________________________________________________________________
197TH2*
ac8cd48d 198AliMemoryWatcher::Frame(void) const
d60522e4 199{
b01af8c2 200 //creates the frame histo in which the graphs will be plotted
201 Double_t xmin=1E30;
202 Double_t xmax=0;
203 Double_t ymin=1;
204 Double_t ymax=0;
205 UInt_t i ;
00399209 206 for (i=0; i < Size() ; i++ ) {
d60522e4 207 if ( X(i) < xmin ) xmin = X(i);
208 if ( X(i) > xmax ) xmax = X(i);
b01af8c2 209 Double_t y = VSIZE(i)+RSSIZE(i);
d60522e4 210 if ( y > ymax ) ymax = y;
d60522e4 211 if ( VSIZE(i) < ymin ) ymin = VSIZE(i);
212 if ( RSSIZE(i) < ymin ) ymin = RSSIZE(i);
213 }
d60522e4 214 TH2F* h = new TH2F("frame","",10,xmin,xmax,10,ymin*0.8,ymax*1.2);
d60522e4 215 return h;
216}
d60522e4 217//_____________________________________________________________________________
6c4904c2 218Int_t
219AliMemoryWatcher::Write(const char *, Int_t, Int_t)
d60522e4 220{
b01af8c2 221 // Stores the graphs in a file
222 if ( GraphVSIZE() ) GraphVSIZE()->Write("VSIZE",TObject::kOverwrite);
00399209 223 if ( GraphRSSIZE() ) GraphRSSIZE() ->Write("RSSIZE",TObject::kOverwrite);
b01af8c2 224 if ( GraphTIME() ) GraphTIME()->Write("TIME",TObject::kOverwrite);
6c4904c2 225 return 0;
4ed9ed00 226}