]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - STEER/AliMemoryWatcher.cxx
Bug fix
[u/mrichter/AliRoot.git] / STEER / AliMemoryWatcher.cxx
... / ...
CommitLineData
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//_________________________________________________________________________
17//Basic Memory Leak utility.
18// You can use this tiny class to *see* if your program is leaking.
19// Usage:
20// AliMemoryWatcher memwatcher;
21// some program loop on events here {
22// if ( nevents % x == 0 )
23// {
24// // take a sample every x events
25// memwatcher.Watch(nevents);
26// }
27// }
28// TFile f("out.root","RECREATE");
29// memwatcher.Write();
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.
44//*-- Author: Laurent Aphecetche(SUBATECH)
45// --- std system ---
46#include <cassert>
47#ifdef __APPLE__
48#include <stdlib.h>
49#else
50#include <malloc.h>
51#endif
52// --- AliRoot header files ---
53#include "AliLog.h"
54#include "AliMemoryWatcher.h"
55// --- ROOT system ---
56#include "TSystem.h"
57#include "TGraph.h"
58#include "TH2.h"
59#include "TStopwatch.h"
60#include "TError.h"
61
62ClassImp(AliMemoryWatcher)
63
64//_____________________________________________________________________________
65AliMemoryWatcher::AliMemoryWatcher(UInt_t maxsize) :
66 TObject(),
67 fUseMallinfo(kTRUE),
68 fPID(gSystem->GetPid()),
69 fMAXSIZE(maxsize),
70 fSize(0),
71 fX(new Int_t[fMAXSIZE]),
72 fVSIZE(new Int_t[fMAXSIZE]),
73 fRSSIZE(new Int_t[fMAXSIZE]),
74 fTIME(new Double_t[fMAXSIZE]),
75 fTimer(0),
76 fDisabled(kFALSE)
77{
78 //
79 //ctor
80 //
81 sprintf(fCmd,"ps -h -p %d -o vsz,rss | grep -v VSZ",fPID);
82}
83
84//_____________________________________________________________________________
85AliMemoryWatcher::AliMemoryWatcher(const AliMemoryWatcher& mw):
86 TObject(mw),
87 fUseMallinfo(mw.fUseMallinfo),
88 fPID(mw.fPID),
89 fMAXSIZE(mw.fMAXSIZE),
90 fSize(0),
91 fX(new Int_t[fMAXSIZE]),
92 fVSIZE(new Int_t[fMAXSIZE]),
93 fRSSIZE(new Int_t[fMAXSIZE]),
94 fTIME(new Double_t[fMAXSIZE]),
95 fTimer(0),
96 fDisabled(kFALSE)
97{
98 //copy ctor
99 strcpy(fCmd, mw.fCmd) ;
100}
101
102//_____________________________________________________________________________
103AliMemoryWatcher::~AliMemoryWatcher()
104{
105 // dtor
106 delete[] fVSIZE;
107 delete[] fRSSIZE;
108 delete[] fX;
109 delete[] fTIME;
110 delete fTimer;
111}
112//_____________________________________________________________________________
113void AliMemoryWatcher::Watch(Int_t x)
114{
115 // Sets the point where CPU parameters have to be monitored
116 if ( !fDisabled && fSize < fMAXSIZE ) {
117 if ( fSize==0 ) {
118 assert(fTimer==0);
119 fTimer = new TStopwatch;
120 fTimer->Start(true);
121 fTimer->Stop();
122 }
123 if ( fUseMallinfo ) {
124#ifdef __linux
125 static struct mallinfo meminfo;
126 meminfo = mallinfo();
127 fX[fSize] = x ;
128 fVSIZE[fSize] = (meminfo.hblkhd + meminfo.uordblks) / 1024;
129 fRSSIZE[fSize] = meminfo.uordblks / 1024;
130 fTIME[fSize] = fTimer->CpuTime();
131 fSize++;
132#else
133 AliFatal("Please SetUseMallinfo to kFALSE on this system");
134#endif
135 } else {
136 static Int_t vsize, rssize;
137 static FILE* pipe = 0;
138 pipe = popen(fCmd,"r");
139 if ( pipe ) {
140
141 fscanf(pipe,"%d %d",&vsize,&rssize);
142
143 fX[fSize] = x ;
144 fVSIZE[fSize] = vsize ;
145 fRSSIZE[fSize] = rssize ;
146 fTIME[fSize] = fTimer->CpuTime();
147 fSize++;
148 }
149 assert(pclose(pipe)!=-1);
150 }
151 fTimer->Start(true);
152 }
153 else {
154 fDisabled=true;
155 AliError("I'm full !" ) ;
156 }
157}
158//_____________________________________________________________________________
159TGraph*
160AliMemoryWatcher::GraphVSIZE(void)
161{
162 // Fills the graph with the virtual memory sized used
163 TGraph* g = 0;
164 if ( Size() )
165 {
166 g = new TGraph(Size());
167 Int_t i ;
168 for (i=0; i < g->GetN(); i++ ) {
169 g->SetPoint(i,X(i),VSIZE(i));
170 }
171 }
172 return g;
173}
174//_____________________________________________________________________________
175TGraph*
176AliMemoryWatcher::GraphRSSIZE(void)
177{
178 // Fills the graph with the real memory sized used
179 TGraph* g = 0;
180 if ( Size() )
181 {
182 g = new TGraph(Size());
183 Int_t i ;
184 for (i=0; i < g->GetN(); i++ ) {
185 g->SetPoint(i,X(i),RSSIZE(i));
186 }
187 }
188 return g;
189}
190//_____________________________________________________________________________
191TGraph*
192AliMemoryWatcher::GraphTIME(void)
193{
194 // Fills the raph with the used CPU time
195 TGraph* g = 0;
196 if ( Size() )
197 {
198 g = new TGraph(Size());
199 Int_t i ;
200 for (i=0; i < g->GetN(); i++ ) {
201 g->SetPoint(i,X(i),TIME(i));
202 }
203 }
204 return g;
205}
206//_____________________________________________________________________________
207TH2*
208AliMemoryWatcher::Frame(void) const
209{
210 //creates the frame histo in which the graphs will be plotted
211 Double_t xmin=1E30;
212 Double_t xmax=0;
213 Double_t ymin=1;
214 Double_t ymax=0;
215 UInt_t i ;
216 for (i=0; i < Size() ; i++ ) {
217 if ( X(i) < xmin ) xmin = X(i);
218 if ( X(i) > xmax ) xmax = X(i);
219 Double_t y = VSIZE(i)+RSSIZE(i);
220 if ( y > ymax ) ymax = y;
221 if ( VSIZE(i) < ymin ) ymin = VSIZE(i);
222 if ( RSSIZE(i) < ymin ) ymin = RSSIZE(i);
223 }
224 TH2F* h = new TH2F("frame","",10,xmin,xmax,10,ymin*0.8,ymax*1.2);
225 return h;
226}
227//_____________________________________________________________________________
228Int_t
229AliMemoryWatcher::WriteToFile()
230{
231 // Stores the graphs in a file
232 if ( GraphVSIZE() ) GraphVSIZE()->Write("VSIZE",TObject::kOverwrite);
233 if ( GraphRSSIZE() ) GraphRSSIZE() ->Write("RSSIZE",TObject::kOverwrite);
234 if ( GraphTIME() ) GraphTIME()->Write("TIME",TObject::kOverwrite);
235 return 0;
236}