0a784deec7d49c8a0798899db382accbba8e57dd
[u/mrichter/AliRoot.git] / PHOS / AliPHOSMemoryWatcher.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     
19     You can use this tiny class to *see* if your program is leaking.
20     Usage:
21     AliPHOSMemoryWatcher memwatcher;
22     some program loop on events here {
23       if ( nevents % x == 0 ) 
24       {
25       // take a sample every x events
26         memwatcher.watch(nevents);
27       }
28     }
29     TFile f("out.root","RECREATE");
30     memwatcher.write();
31     f.Close();
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     
44     But by fitting the VSIZE by a pol1 under ROOT, you'll see right away
45     by how much your program is leaking.
46 */             
47 //*-- Author: Laurent Aphecetche(SUBATECH)
48 // --- std system ---
49 #include <iostream>
50 #include <cstdio>
51 #include <cstdlib>
52 #include <cassert>
53 // --- AliRoot header files ---
54 #include "AliPHOSMemoryWatcher.h"
55 // --- ROOT system ---
56 #include "TSystem.h"
57 #include "TGraph.h"
58 #include "TH2.h"
59 #include "TStopwatch.h"
60 //_____________________________________________________________________________
61 AliPHOSMemoryWatcher::AliPHOSMemoryWatcher(unsigned int maxsize)
62 {
63   fMAXSIZE=maxsize;
64   fPID = gSystem->GetPid();
65   sprintf(fCmd,"ps -h -p %d -o vsize,rssize",fPID);
66   fX = new int[fMAXSIZE];
67   fVSIZE = new int[fMAXSIZE];
68   fRSSIZE = new int[fMAXSIZE];
69   fTIME = new double[fMAXSIZE];
70   fSize=0;
71   fDisabled=false;
72   fTimer=0;
73 }
74 //_____________________________________________________________________________
75 AliPHOSMemoryWatcher::~AliPHOSMemoryWatcher()
76 {
77   delete[] fVSIZE;
78   delete[] fRSSIZE;
79   delete[] fX;
80   delete[] fTIME;
81   delete fTimer;
82 }
83 //_____________________________________________________________________________
84 void AliPHOSMemoryWatcher::watch(int x)
85 {
86   if ( !fDisabled && fSize < fMAXSIZE ) {
87     if ( fSize==0 ) {
88       assert(fTimer==0);
89       fTimer = new TStopwatch;
90       fTimer->Start(true);
91       fTimer->Stop();
92     }
93     static int vsize, rssize;
94     static FILE* pipe = 0;
95     pipe = popen(fCmd,"r");
96     if ( pipe ) {
97     
98       fscanf(pipe,"%d %d",&vsize,&rssize);
99       
100       fX[fSize] = x ;
101       fVSIZE[fSize] = vsize ;
102       fRSSIZE[fSize] = rssize ;
103       fTIME[fSize] = fTimer->CpuTime();
104       fSize++;
105     }
106     assert(pclose(pipe)!=-1);
107     fTimer->Start(true);
108   }
109   else {
110     fDisabled=true;
111     cerr << "AliPHOSMemoryWatcher::watch : I'm full !" << endl;
112   }
113 }
114 //_____________________________________________________________________________
115 TGraph*
116 AliPHOSMemoryWatcher::graphVSIZE(void)
117 {
118   TGraph* g = 0;
119   if ( size() )
120     {
121       g = new TGraph(size());
122       for (int i=0; i < g->GetN(); i++ ) {
123         g->SetPoint(i,X(i),VSIZE(i));
124       }
125     }
126   return g;
127 }
128 //_____________________________________________________________________________
129 TGraph*
130 AliPHOSMemoryWatcher::graphRSSIZE(void)
131 {
132   TGraph* g = 0;
133   if ( size() ) 
134     {
135       g = new TGraph(size());
136       for (int i=0; i < g->GetN(); i++ ) {
137         g->SetPoint(i,X(i),RSSIZE(i));
138       }
139     }
140   return g;
141 }
142 //_____________________________________________________________________________
143 TGraph*
144 AliPHOSMemoryWatcher::graphTIME(void)
145 {
146   TGraph* g = 0;
147   if ( size() ) 
148     {
149       g = new TGraph(size());
150       for (int i=0; i < g->GetN(); i++ ) {
151         g->SetPoint(i,X(i),TIME(i));
152       }
153     }
154   return g;
155 }
156 //_____________________________________________________________________________
157 TH2*
158 AliPHOSMemoryWatcher::frame(void)
159 {
160   double xmin=1E30;
161   double xmax=0;
162   double ymin=1;
163   double ymax=0;
164   for (unsigned int i=0; i < size() ; i++ ) {
165     if ( X(i) < xmin ) xmin = X(i);
166     if ( X(i) > xmax ) xmax = X(i);
167     double y = VSIZE(i)+RSSIZE(i);
168     if ( y > ymax ) ymax = y;
169     if ( VSIZE(i) < ymin ) ymin = VSIZE(i);
170     if ( RSSIZE(i) < ymin ) ymin = RSSIZE(i);
171   }
172   TH2F* h = new TH2F("frame","",10,xmin,xmax,10,ymin*0.8,ymax*1.2);
173   return h;
174 }
175 //_____________________________________________________________________________
176 void 
177 AliPHOSMemoryWatcher::write(void)
178 {
179   if ( graphVSIZE() ) graphVSIZE()->Write("VSIZE",TObject::kOverwrite);
180   if ( graphRSSIZE() ) graphRSSIZE()->Write("RSSIZE",TObject::kOverwrite);
181   if ( graphTIME() ) graphTIME()->Write("TIME",TObject::kOverwrite);
182 }