7 #if defined(linux) || defined(__linux) 9 #include "fwMemory/tools/PosixMemoryMonitorTools.hpp" 11 #include <fwCore/base.hpp> 16 #include <boost/filesystem/convenience.hpp> 17 #include <boost/filesystem/operations.hpp> 18 #include <boost/filesystem/path.hpp> 19 #include <boost/lexical_cast.hpp> 20 #include <boost/regex.hpp> 22 #include <sys/resource.h> 24 #include <sys/types.h> 41 std::uint64_t PosixMemoryMonitorTools::s_pageSize = sysconf(_SC_PAGE_SIZE);
42 std::uint64_t PosixMemoryMonitorTools::s_totalMemory = sysconf(_SC_PHYS_PAGES) * s_pageSize;
46 PosixMemoryMonitorTools::PosixMemoryMonitorTools()
52 PosixMemoryMonitorTools::~PosixMemoryMonitorTools()
58 std::uint64_t PosixMemoryMonitorTools::estimateFreeMem()
60 std::uint64_t freeMemory = 0;
70 freeMemory = getFreeSystemMemory();
77 void PosixMemoryMonitorTools::printProcessMemoryInformation()
80 getStatusOfPid( getpid(), stat );
86 void PosixMemoryMonitorTools::printSystemMemoryInformation()
89 get_memory_stats(memory);
90 std::uint64_t oToKMo = 1024*1024;
92 OSLM_INFO(
"Total memory: " << memory.total/oToKMo<<
" Mo");
93 OSLM_INFO(
"Free memory: " << memory.free/oToKMo <<
" Mo");
94 OSLM_INFO(
"Buffered: " << memory.buffered/oToKMo <<
" Mo");
95 OSLM_INFO(
"Cached: " << memory.cached/oToKMo <<
" Mo");
96 OSLM_INFO(
"Swap Cached: " << memory.swapcached/oToKMo <<
" Mo");
97 OSLM_INFO(
"Swap Total: " << memory.swaptotal/oToKMo <<
" Mo");
98 OSLM_INFO(
"Swap Free: " << memory.swapfree/oToKMo <<
" Mo");
101 getAllStatus( allStat );
102 printStatus( allStat );
104 std::uint64_t computedFree = ( memory.total - allStat.VmRSS ) / oToKMo;
105 std::uint64_t free = memory.free / oToKMo;
106 OSLM_INFO(
"(ComputedFree, Free, Diff) - ( " 107 << std::setw(5) << computedFree
108 << std::setw(5) << free
109 << std::setw(5) << computedFree -free
117 void PosixMemoryMonitorTools::printMemoryInformation()
119 printSystemMemoryInformation();
120 printProcessMemoryInformation();
125 std::uint64_t PosixMemoryMonitorTools::getTotalSystemMemory()
127 return s_totalMemory;
132 std::uint64_t PosixMemoryMonitorTools::getUsedSystemMemory()
134 return getTotalSystemMemory() - getFreeSystemMemory();
139 std::uint64_t PosixMemoryMonitorTools::getFreeSystemMemory()
144 get_memory_stats(memory);
145 return sysconf(_SC_AVPHYS_PAGES) * s_pageSize + memory.cached;
150 std::uint64_t PosixMemoryMonitorTools::getUsedProcessMemory()
153 getStatusOfPid( getpid(), stat );
161 std::uint64_t PosixMemoryMonitorTools::extract_number(
char* str,
int start,
int end)
166 for (i = start, j = 0; i < end; i++)
168 isdigit(str[i]) && (buf[j++] = str[i]);
172 return strtoul(buf, NULL, 0) * 1024;
177 void PosixMemoryMonitorTools::get_memory_stats( MemInfo& meminfo )
199 std::ifstream input(
"/proc/meminfo" );
202 if ( input.is_open() )
204 while ( !input.eof() )
206 getline( input, line );
207 analyseMemInfo( line, meminfo );
216 void PosixMemoryMonitorTools::analyseMemInfo( std::string& line, MemInfo& meminfo )
218 ::boost::regex e(
"([A-Za-z:]+)([ \t]+)([0-9]+)([ \t]+)kB(.*)");
219 std::string machine_format =
"\\3";
220 if ( line.find(
"MemTotal") != std::string::npos )
222 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
223 meminfo.total = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
225 else if ( line.find(
"MemFree") != std::string::npos )
227 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
228 meminfo.free = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
230 else if ( line.find(
"Buffers") != std::string::npos )
232 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
233 meminfo.buffered = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
235 else if ( line.find(
"SwapCached") != std::string::npos )
237 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
238 meminfo.swapcached = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
240 else if ( line.find(
"Cached") != std::string::npos )
242 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
243 meminfo.cached = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
245 else if ( line.find(
"SwapTotal") != std::string::npos )
247 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
248 meminfo.swaptotal = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
250 else if ( line.find(
"SwapFree") != std::string::npos )
252 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
253 meminfo.swapfree = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
260 void PosixMemoryMonitorTools::printStatus( Status& stat )
262 int oToMo = 1024 * 1024;
263 OSLM_DEBUG(
"VmPeak = " << stat.VmPeak / oToMo <<
" Mo" );
264 OSLM_DEBUG(
"VmSize = " << stat.VmSize / oToMo <<
" Mo" );
265 OSLM_DEBUG(
"VmLck = " << stat.VmLck / oToMo <<
" Mo" );
266 OSLM_DEBUG(
"VmHWM = " << stat.VmHWM / oToMo <<
" Mo" );
267 OSLM_DEBUG(
"VmRSS = " << stat.VmRSS / oToMo <<
" Mo" );
268 OSLM_DEBUG(
"VmData = " << stat.VmData / oToMo <<
" Mo" );
269 OSLM_DEBUG(
"VmStk = " << stat.VmStk / oToMo <<
" Mo" );
270 OSLM_DEBUG(
"VmExe = " << stat.VmExe / oToMo <<
" Mo" );
271 OSLM_DEBUG(
"VmLib = " << stat.VmLib / oToMo <<
" Mo" );
272 OSLM_DEBUG(
"VmPTE = " << stat.VmPTE / oToMo <<
" Mo" );
278 void PosixMemoryMonitorTools::analyseStatusLine( std::string& line, Status& stat )
280 ::boost::regex e(
"([A-Za-z:]+)([ \t]+)([0-9]+)([ \t]+)kB(.*)");
281 std::string machine_format =
"\\3";
282 if ( line.find(
"VmPeak") != std::string::npos )
284 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
285 stat.VmPeak = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
287 else if ( line.find(
"VmSize") != std::string::npos )
289 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
290 stat.VmSize = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
292 else if ( line.find(
"VmLck") != std::string::npos )
294 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
295 stat.VmLck = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
297 else if ( line.find(
"VmHWM") != std::string::npos )
299 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
300 stat.VmHWM = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
302 else if ( line.find(
"VmRSS") != std::string::npos )
304 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
305 stat.VmRSS = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
307 else if ( line.find(
"VmData") != std::string::npos )
309 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
310 stat.VmData = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
312 else if ( line.find(
"VmStk") != std::string::npos )
314 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
315 stat.VmStk = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
317 else if ( line.find(
"VmExe") != std::string::npos )
319 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
320 stat.VmExe = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
322 else if ( line.find(
"VmLib") != std::string::npos )
324 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
325 stat.VmLib = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
327 else if ( line.find(
"VmPTE") != std::string::npos )
329 std::string size = regex_replace(line, e, machine_format, ::boost::match_default | ::boost::format_sed);
330 stat.VmPTE = ::boost::lexical_cast< std::uint64_t >(size) * 1024;
336 void PosixMemoryMonitorTools::getStatusOfPid(
int pid, Status& stat)
338 std::stringstream file;
339 file <<
"/proc/" << pid <<
"/status";
340 std::ifstream input( file.str().c_str() );
343 if ( input.is_open() )
345 while ( !input.eof() )
347 getline( input, line );
348 analyseStatusLine(line, stat);
356 void PosixMemoryMonitorTools::getAllStatus( Status& allStat )
358 ::boost::filesystem::path path(
"/proc");
359 ::boost::regex e(
"[0-9]+");
372 for( ::boost::filesystem::directory_iterator it(path);
373 it != ::boost::filesystem::directory_iterator();
377 if( ::boost::filesystem::is_directory(*it) )
379 ::boost::filesystem::path tmpPath = (*it);
380 std::string dirName = tmpPath.filename().string();
381 if ( regex_match(dirName, e) )
383 int pid = strtoul(dirName.c_str(), NULL, 0);
385 getStatusOfPid( pid, stat);
386 allStat.VmPeak += stat.VmPeak;
387 allStat.VmSize += stat.VmSize;
388 allStat.VmLck += stat.VmLck;
389 allStat.VmHWM += stat.VmHWM;
390 allStat.VmRSS += stat.VmRSS;
391 allStat.VmData += stat.VmData;
392 allStat.VmStk += stat.VmStk;
393 allStat.VmExe += stat.VmExe;
394 allStat.VmLib += stat.VmLib;
395 allStat.VmPTE += stat.VmPTE;
403 void PosixMemoryMonitorTools::printAllStatus()
405 ::boost::filesystem::path path(
"/proc");
406 ::boost::regex e(
"[0-9]+");
407 int oToMo = 1024 * 1024;
409 std::uint64_t totalVmPeak = 0;
410 std::uint64_t totalVmSize = 0;
411 std::uint64_t totalVmLck = 0;
412 std::uint64_t totalVmHWM = 0;
413 std::uint64_t totalVmRSS = 0;
414 std::uint64_t totalVmData = 0;
415 std::uint64_t totalVmStk = 0;
416 std::uint64_t totalVmExe = 0;
417 std::uint64_t totalVmLib = 0;
418 std::uint64_t totalVmPTE = 0;
420 for( ::boost::filesystem::directory_iterator it(path);
421 it != ::boost::filesystem::directory_iterator();
425 if( ::boost::filesystem::is_directory(*it) )
427 ::boost::filesystem::path tmpPath = (*it);
428 std::string dirName = tmpPath.filename().string();
429 if ( regex_match(dirName, e) )
431 int pid = strtoul(dirName.c_str(), NULL, 0);
433 getStatusOfPid( pid, stat);
434 totalVmPeak += stat.VmPeak;
435 totalVmSize += stat.VmSize;
436 totalVmLck += stat.VmLck;
437 totalVmHWM += stat.VmHWM;
438 totalVmRSS += stat.VmRSS;
439 totalVmData += stat.VmData;
440 totalVmStk += stat.VmStk;
441 totalVmExe += stat.VmExe;
442 totalVmLib += stat.VmLib;
443 totalVmPTE += stat.VmPTE;
447 totalVmPeak /= oToMo;
448 totalVmSize /= oToMo;
452 totalVmData /= oToMo;
458 OSLM_DEBUG(
"( " << totalVmPeak << std::setw(5) << totalVmSize << std::setw(5) << totalVmLck << std::setw(
459 5) << totalVmHWM << std::setw(5) << totalVmRSS << std::setw(5) << totalVmData << std::setw(
460 5) << totalVmStk << std::setw(5) << totalVmExe << std::setw(5) << totalVmLib << std::setw(
461 5) << totalVmPTE <<
" )");
480 #endif //defined(linux) || defined(__linux) The namespace fwMemory contains tools to manage memory. Use for dump.
#define OSLM_INFO(message)
The namespace memory contains tools to manage memory. It is used for dump. It allows to define the bu...
#define OSLM_DEBUG(message)