]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliMemoryWatcher.cxx
Execution time printout via AliInfo
[u/mrichter/AliRoot.git] / STEER / AliMemoryWatcher.cxx
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
62 ClassImp(AliMemoryWatcher)
63
64 //_____________________________________________________________________________
65 AliMemoryWatcher::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 //_____________________________________________________________________________
85 AliMemoryWatcher::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 //_____________________________________________________________________________
103 AliMemoryWatcher::~AliMemoryWatcher()
104 {
105   // dtor
106   delete[] fVSIZE;
107   delete[] fRSSIZE;
108   delete[] fX;
109   delete[] fTIME;
110   delete fTimer;
111 }
112 //_____________________________________________________________________________
113 void 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 //_____________________________________________________________________________
159 TGraph*
160 AliMemoryWatcher::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 //_____________________________________________________________________________
175 TGraph*
176 AliMemoryWatcher::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 //_____________________________________________________________________________
191 TGraph*
192 AliMemoryWatcher::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 //_____________________________________________________________________________
207 TH2*
208 AliMemoryWatcher::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 //_____________________________________________________________________________
228 Int_t
229 AliMemoryWatcher::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 }