]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliMemoryWatcher.cxx
Set values to zero in constructor. Added print function.
[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 class assert ; 
47 // --- AliRoot header files ---
48 #include "AliMemoryWatcher.h"
49 // --- ROOT system ---
50 #include "TSystem.h"
51 #include "TGraph.h"
52 #include "TH2.h"
53 #include "TStopwatch.h"
54
55 ClassImp(AliMemoryWatcher)
56
57 //_____________________________________________________________________________
58 AliMemoryWatcher::AliMemoryWatcher(UInt_t maxsize)
59 {
60   //ctor
61   fMAXSIZE=maxsize;
62   fPID = gSystem->GetPid();
63   sprintf(fCmd,"ps -h -p %d -o vsize,rssize",fPID);
64   fX = new Int_t[fMAXSIZE];
65   fVSIZE = new Int_t[fMAXSIZE];
66   fRSSIZE = new Int_t[fMAXSIZE];
67   fTIME = new Double_t[fMAXSIZE];
68   fSize=0;
69   fDisabled=false;
70   fTimer=0;
71 }
72 //_____________________________________________________________________________
73 AliMemoryWatcher::AliMemoryWatcher(const AliMemoryWatcher& mw):
74   TObject(mw)
75 {
76   //copy ctor
77   fMAXSIZE = mw.fMAXSIZE ;
78   fPID = mw.fPID ; 
79   strcpy(fCmd, mw.fCmd) ; 
80   fX = new Int_t[fMAXSIZE];
81   fVSIZE = new Int_t[fMAXSIZE];
82   fRSSIZE = new Int_t[fMAXSIZE];
83   fTIME = new Double_t[fMAXSIZE];
84   fSize=0;
85   fDisabled=false;
86   fTimer=0;   
87 }
88 //_____________________________________________________________________________
89 AliMemoryWatcher::~AliMemoryWatcher()
90 {
91   // dtor
92   delete[] fVSIZE;
93   delete[] fRSSIZE;
94   delete[] fX;
95   delete[] fTIME;
96   delete fTimer;
97 }
98 //_____________________________________________________________________________
99 void AliMemoryWatcher::Watch(Int_t x)
100 {
101   // Sets the point where CPU parameters have to be monitored
102   if ( !fDisabled && fSize < fMAXSIZE ) {
103     if ( fSize==0 ) {
104       assert(fTimer==0);
105       fTimer = new TStopwatch;
106       fTimer->Start(true);
107       fTimer->Stop();
108     }
109     static Int_t vsize, rssize;
110     static FILE* pipe = 0;
111     pipe = popen(fCmd,"r");
112     if ( pipe ) {
113     
114       fscanf(pipe,"%d %d",&vsize,&rssize);
115       
116       fX[fSize] = x ;
117       fVSIZE[fSize] = vsize ;
118       fRSSIZE[fSize] = rssize ;
119       fTIME[fSize] = fTimer->CpuTime();
120       fSize++;
121     }
122     assert(pclose(pipe)!=-1);
123     fTimer->Start(true);
124   }
125   else {
126     fDisabled=true;
127     Error("watch", "I'm full !" ) ;
128   }
129 }
130 //_____________________________________________________________________________
131 TGraph*
132 AliMemoryWatcher::GraphVSIZE(void)
133 {
134   // Fills the graph with the virtual memory sized used
135   TGraph* g = 0;
136   if ( Size() )
137     {
138       g = new TGraph(Size());
139       Int_t i ; 
140       for (i=0; i < g->GetN(); i++ ) {
141         g->SetPoint(i,X(i),VSIZE(i));
142       }
143     }
144   return g;
145 }
146 //_____________________________________________________________________________
147 TGraph*
148 AliMemoryWatcher::GraphRSSIZE(void)
149 {
150   // Fills the graph with the real memory sized used
151   TGraph* g = 0;
152   if ( Size() ) 
153     {
154       g = new TGraph(Size());
155       Int_t i ; 
156       for (i=0; i < g->GetN(); i++ ) {
157         g->SetPoint(i,X(i),RSSIZE(i));
158       }
159     }
160   return g;
161 }
162 //_____________________________________________________________________________
163 TGraph*
164 AliMemoryWatcher::GraphTIME(void)
165 {
166   // Fills the raph with the used CPU time
167   TGraph* g = 0;
168   if ( Size() ) 
169     {
170       g = new TGraph(Size());
171       Int_t i ; 
172       for (i=0; i < g->GetN(); i++ ) {
173         g->SetPoint(i,X(i),TIME(i));
174       }
175     }
176   return g;
177 }
178 //_____________________________________________________________________________
179 TH2*
180 AliMemoryWatcher::Frame(void) const
181 {
182   //creates the frame histo in which the graphs will be plotted 
183   Double_t xmin=1E30;
184   Double_t xmax=0;
185   Double_t ymin=1;
186   Double_t ymax=0;
187   UInt_t i ; 
188   for (i=0; i < Size() ; i++ ) {
189     if ( X(i) < xmin ) xmin = X(i);
190     if ( X(i) > xmax ) xmax = X(i);
191     Double_t y = VSIZE(i)+RSSIZE(i);
192     if ( y > ymax ) ymax = y;
193     if ( VSIZE(i) < ymin ) ymin = VSIZE(i);
194     if ( RSSIZE(i) < ymin ) ymin = RSSIZE(i);
195   }
196   TH2F* h = new TH2F("frame","",10,xmin,xmax,10,ymin*0.8,ymax*1.2);
197   return h;
198 }
199 //_____________________________________________________________________________
200 Int_t
201 AliMemoryWatcher::Write(const char *, Int_t, Int_t)
202 {
203   // Stores the graphs in a file 
204   if ( GraphVSIZE() ) GraphVSIZE()->Write("VSIZE",TObject::kOverwrite);
205   if ( GraphRSSIZE() ) GraphRSSIZE() ->Write("RSSIZE",TObject::kOverwrite);
206   if ( GraphTIME() ) GraphTIME()->Write("TIME",TObject::kOverwrite);
207   return 0;
208 }