Home || Visual Search || Applications || Architecture || Important Messages || OGL || Src

MemoryInfo.h

Go to the documentation of this file.
00001 #ifndef Impala_Process_MemoryInfo_h
00002 #define Impala_Process_MemoryInfo_h
00003 
00004 #include "Basis/ILog.h"
00005 #include "Basis/String.h"
00006 #include "Basis/NativeTypes.h"
00007 #ifdef WIN32
00008 #include <psapi.h>
00009 #else
00010 #include <unistd.h>
00011 #endif
00012 #include <vector>
00013 
00014 namespace Impala
00015 {
00016 namespace Process
00017 {
00018 
00019 class MemoryInfo
00020 {
00021 public:
00022 
00023     MemoryInfo(CString tag, int dumpFreq)
00024     {
00025         mTag = tag;
00026         mDumpFreq = dumpFreq;
00027         mIsActive = false;
00028         mTotalMemIncr = 0;
00029         mMemFrom = 0;
00030         mNrCalls = 0;
00031         mNrCallsIncr = 0;
00032         mNrCallsDecr = 0;
00033     }
00034 
00035     // returns -1 if not supported; -2 if retrieval failed
00036     static Int64
00037     GetUsage()
00038     {
00039         Int64 usage = -1;
00040 #ifdef WIN32
00041         PROCESS_MEMORY_COUNTERS info;
00042         bool result = GetProcessMemoryInfo(GetCurrentProcess(), &info,
00043                                            sizeof(info));
00044         if (result)
00045         {
00046             usage = info.WorkingSetSize + info.QuotaPagedPoolUsage +
00047                 info.QuotaNonPagedPoolUsage + info.PagefileUsage;
00048         }
00049         else
00050         {
00051             usage = -2;
00052         }
00053 #else
00054         long pageSize = sysconf(_SC_PAGE_SIZE);
00055         char buf[100];
00056         sprintf(buf, "/proc/%u/statm", (unsigned) getpid());
00057         FILE* fp = fopen(buf, "r");
00058         if (fp)
00059         {
00060             unsigned size;
00061             fscanf(fp, "%u", &size);
00062             usage = (Int64) size * (Int64) pageSize;
00063             fclose(fp);
00064         }
00065         else
00066         {
00067             usage = -2;
00068         }
00069 #endif
00070         return usage;
00071     }
00072 
00073     static String
00074     GetUsageString()
00075     {
00076         Int64 usage = GetUsage();
00077         if (usage < 0)
00078             return "no memory info available";
00079         return Bytes2String(usage);
00080     }
00081 
00082     static String
00083     Bytes2String(Int64 nr)
00084     {
00085         const char* units[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB"};
00086         String sign("");
00087         if (nr < 0)
00088         {
00089             sign = "-";
00090             nr = -nr;
00091         }
00092         std::vector<int> vec;
00093         for (int i=0 ; i<7 ; i++)
00094         {
00095             vec.push_back(nr % 1024);
00096             nr /= 1024;
00097         }
00098         if (nr != 0)
00099             return "Out of range";
00100         int u = 6;
00101         while ((vec[u] == 0) && (u > 0))
00102             u--;
00103         String val = MakeString(vec[u]);
00104         if (u > 0)
00105             val += "." + MakeString(vec[u-1]);
00106         return sign + val + String(units[u]);
00107     }
00108 
00109     static void
00110     PrintUsage(CString message)
00111     {
00112         ILOG_INFO("print usage");
00113         Int64 nr = GetUsage();
00114         if (nr < 0)
00115         {
00116             ILOG_INFO("Could not establish memory usage");
00117         }
00118         else
00119         {
00120             ILOG_INFO(message << ", usage = " << nr << " = " << Bytes2String(nr));
00121         }
00122     }
00123 
00124     void
00125     MarkFrom()
00126     {
00127         if (mIsActive)
00128         {
00129             ILOG_WARN("Already active (" << mTag << ")");
00130             return;
00131         }
00132         mMemFrom = GetUsage();
00133         mIsActive = true;
00134     }
00135 
00136     Int64
00137     GetUsageSinceMark()
00138     {
00139         if (!mIsActive)
00140         {
00141             ILOG_WARN("Not active (" << mTag << ")");
00142             return -1;
00143         }
00144         return GetUsage() - mMemFrom;
00145     }
00146 
00147     String
00148     GetUsageSinceMarkString()
00149     {
00150         if (!mIsActive)
00151         {
00152             ILOG_WARN("Not active (" << mTag << ")");
00153             return "not active";
00154         }
00155         Int64 memIncr = GetUsage() - mMemFrom;
00156         return Bytes2String(memIncr);
00157     }
00158 
00159     void
00160     MarkTo()
00161     {
00162         if (!mIsActive)
00163         {
00164             ILOG_WARN("Not active (" << mTag << ")");
00165             return;
00166         }
00167         mNrCalls++;
00168         Int64 memTo = GetUsage();
00169         Int64 memIncr = memTo - mMemFrom;
00170         if (memIncr != 0)
00171         {
00172             if (mMemFrom < memTo)
00173                 mNrCallsIncr++;
00174             else
00175                 mNrCallsDecr++;
00176             mTotalMemIncr += memIncr;
00177         }
00178         mIsActive = false;
00179 
00180         if (mDumpFreq > 0)
00181             if (mNrCalls % mDumpFreq == 0)
00182                 Dump();
00183     }
00184 
00185     void
00186     Dump()
00187     {
00188         if (mIsActive)
00189             ILOG_WARN("Still active (" << mTag << ")");
00190 
00191         Int64 avg = mTotalMemIncr / Int64(mNrCalls);
00192         ILOG_INFO("Dump (" << mTag << ") : " <<
00193                   "NrCalls=" << mNrCalls <<
00194                   ", TotalMemIncr=" << mTotalMemIncr <<
00195                   " (" << Bytes2String(mTotalMemIncr) << ")" <<
00196                   ", AvgMemIncr=" << avg <<
00197                   " (" << Bytes2String(avg) << ")" <<
00198                   ", NrCallsIncr=" << mNrCallsIncr <<
00199                   ", NrCallsDecr=" << mNrCallsDecr);
00200     }
00201 
00202 private:
00203 
00204     String mTag;
00205     int    mDumpFreq;
00206     bool   mIsActive;
00207     Int64  mTotalMemIncr;
00208     Int64  mMemFrom;
00209     int    mNrCalls;
00210     int    mNrCallsIncr;
00211     int    mNrCallsDecr;
00212 
00213     ILOG_VAR_DECL;
00214 
00215 }; //class
00216 
00217 ILOG_VAR_INIT(MemoryInfo, Impala.Process);
00218 
00219 } // namespace 
00220 } // namespace 
00221 
00222 #endif

Generated on Thu Jan 13 09:05:14 2011 for ImpalaSrc by  doxygen 1.5.1