a19084a7c00767fb4eb9e25ecdf84865dbabcba7
[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 <stdio.h>
50 #include <stdlib.h>
51 #include <assert.h>
52 // --- AliRoot header files ---
53 #include "AliPHOSMemoryWatcher.h"
54 // --- ROOT system ---
55 #include "TSystem.h"
56 #include "TGraph.h"
57 #include "TH2.h"
58 #include "TStopwatch.h"
59 //_____________________________________________________________________________
60 AliPHOSMemoryWatcher::AliPHOSMemoryWatcher(unsigned int maxsize)
61 {
62   fMAXSIZE=maxsize;
63   fPID = gSystem->GetPid();
64   sprintf(fCmd,"ps -h -p %d -o vsize,rssize",fPID);
65   fX = new int[fMAXSIZE];
66   fVSIZE = new int[fMAXSIZE];
67   fRSSIZE = new int[fMAXSIZE];
68   fTIME = new double[fMAXSIZE];
69   fSize=0;
70   fDisabled=false;
71   fTimer=0;
72 }
73 //_____________________________________________________________________________
74 AliPHOSMemoryWatcher::~AliPHOSMemoryWatcher()
75 {
76   delete[] fVSIZE;
77   delete[] fRSSIZE;
78   delete[] fX;
79   delete[] fTIME;
80   delete fTimer;
81 }
82 //_____________________________________________________________________________
83 void AliPHOSMemoryWatcher::watch(int x)
84 {
85   if ( !fDisabled && fSize < fMAXSIZE ) {
86     if ( fSize==0 ) {
87       assert(fTimer==0);
88       fTimer = new TStopwatch;
89       fTimer->Start(true);
90       fTimer->Stop();
91     }
92     static int vsize, rssize;
93     static FILE* pipe = 0;
94     pipe = popen(fCmd,"r");
95     if ( pipe ) {
96     
97       fscanf(pipe,"%d %d",&vsize,&rssize);
98       
99       fX[fSize] = x ;
100       fVSIZE[fSize] = vsize ;
101       fRSSIZE[fSize] = rssize ;
102       fTIME[fSize] = fTimer->CpuTime();
103       fSize++;
104     }
105     assert(pclose(pipe)!=-1);
106     fTimer->Start(true);
107   }
108   else {
109     fDisabled=true;
110     Error("watch", "I'm full !" ) ;
111   }
112 }
113 //_____________________________________________________________________________
114 TGraph*
115 AliPHOSMemoryWatcher::graphVSIZE(void)
116 {
117   TGraph* g = 0;
118   if ( size() )
119     {
120       g = new TGraph(size());
121       for (int i=0; i < g->GetN(); i++ ) {
122         g->SetPoint(i,X(i),VSIZE(i));
123       }
124     }
125   return g;
126 }
127 //_____________________________________________________________________________
128 TGraph*
129 AliPHOSMemoryWatcher::graphRSSIZE(void)
130 {
131   TGraph* g = 0;
132   if ( size() ) 
133     {
134       g = new TGraph(size());
135       for (int i=0; i < g->GetN(); i++ ) {
136         g->SetPoint(i,X(i),RSSIZE(i));
137       }
138     }
139   return g;
140 }
141 //_____________________________________________________________________________
142 TGraph*
143 AliPHOSMemoryWatcher::graphTIME(void)
144 {
145   TGraph* g = 0;
146   if ( size() ) 
147     {
148       g = new TGraph(size());
149       for (int i=0; i < g->GetN(); i++ ) {
150         g->SetPoint(i,X(i),TIME(i));
151       }
152     }
153   return g;
154 }
155 //_____________________________________________________________________________
156 TH2*
157 AliPHOSMemoryWatcher::frame(void)
158 {
159   double xmin=1E30;
160   double xmax=0;
161   double ymin=1;
162   double ymax=0;
163   for (unsigned int i=0; i < size() ; i++ ) {
164     if ( X(i) < xmin ) xmin = X(i);
165     if ( X(i) > xmax ) xmax = X(i);
166     double y = VSIZE(i)+RSSIZE(i);
167     if ( y > ymax ) ymax = y;
168     if ( VSIZE(i) < ymin ) ymin = VSIZE(i);
169     if ( RSSIZE(i) < ymin ) ymin = RSSIZE(i);
170   }
171   TH2F* h = new TH2F("frame","",10,xmin,xmax,10,ymin*0.8,ymax*1.2);
172   return h;
173 }
174 //_____________________________________________________________________________
175 void 
176 AliPHOSMemoryWatcher::write(void)
177 {
178   if ( graphVSIZE() ) graphVSIZE()->Write("VSIZE",TObject::kOverwrite);
179   if ( graphRSSIZE() ) graphRSSIZE()->Write("RSSIZE",TObject::kOverwrite);
180   if ( graphTIME() ) graphTIME()->Write("TIME",TObject::kOverwrite);
181 }