Мне нужно получить использование памяти VIRT и RES во время выполнения моей программы и отобразить их.
Что я пробовал до сих пор:
getrusage ( http://linux.die.net/man/2/getrusage )
int who = RUSAGE_SELF;
struct rusage usage;
int ret;
ret=getrusage(who,&usage);
cout<<usage.ru_maxrss;
но я всегда получаю 0.
Ответы:
В Linux я никогда не находил решения ioctl () . Для наших приложений мы написали общую служебную программу, основанную на чтении файлов в / proc / pid . Есть несколько таких файлов, которые дают разные результаты. Вот тот, на котором мы остановились (вопрос был помечен как C ++, и мы обрабатывали ввод-вывод с помощью конструкций C ++, но он должен быть легко адаптирован к подпрограммам ввода-вывода C, если вам нужно):
#include <unistd.h> #include <ios> #include <iostream> #include <fstream> #include <string> ////////////////////////////////////////////////////////////////////////////// // // process_mem_usage(double &, double &) - takes two doubles by reference, // attempts to read the system-dependent data for a process' virtual memory // size and resident set size, and return the results in KB. // // On failure, returns 0.0, 0.0 void process_mem_usage(double& vm_usage, double& resident_set) { using std::ios_base; using std::ifstream; using std::string; vm_usage = 0.0; resident_set = 0.0; // 'file' stat seems to give the most reliable results // ifstream stat_stream("/proc/self/stat",ios_base::in); // dummy vars for leading entries in stat that we don't care about // string pid, comm, state, ppid, pgrp, session, tty_nr; string tpgid, flags, minflt, cminflt, majflt, cmajflt; string utime, stime, cutime, cstime, priority, nice; string O, itrealvalue, starttime; // the two fields we want // unsigned long vsize; long rss; stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt >> utime >> stime >> cutime >> cstime >> priority >> nice >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest stat_stream.close(); long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages vm_usage = vsize / 1024.0; resident_set = rss * page_size_kb; } int main() { using std::cout; using std::endl; double vm, rss; process_mem_usage(vm, rss); cout << "VM: " << vm << "; RSS: " << rss << endl; }
источник
why 1024.0?
- Он говорит компилятору преобразовать в double FIRST, а затем выполнить деление, чтобы получить двойной результат. Другой вариант:vm_usage = vsize / 1024;
сначала будет делить (теряя точность, как указано в @DonWakefield), а затем преобразовать в double.Дэвид Роберт Надо разместил на своем веб-сайте хорошую автономную многоплатформенную функцию C, чтобы получить размер резидентного набора процесса (использование физической памяти) :
/* * Author: David Robert Nadeau * Site: http://NadeauSoftware.com/ * License: Creative Commons Attribution 3.0 Unported License * http://creativecommons.org/licenses/by/3.0/deed.en_US */ #if defined(_WIN32) #include <windows.h> #include <psapi.h> #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) #include <unistd.h> #include <sys/resource.h> #if defined(__APPLE__) && defined(__MACH__) #include <mach/mach.h> #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) #include <fcntl.h> #include <procfs.h> #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) #include <stdio.h> #endif #else #error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS." #endif /** * Returns the peak (maximum so far) resident set size (physical * memory use) measured in bytes, or zero if the value cannot be * determined on this OS. */ size_t getPeakRSS( ) { #if defined(_WIN32) /* Windows -------------------------------------------------- */ PROCESS_MEMORY_COUNTERS info; GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); return (size_t)info.PeakWorkingSetSize; #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) /* AIX and Solaris ------------------------------------------ */ struct psinfo psinfo; int fd = -1; if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 ) return (size_t)0L; /* Can't open? */ if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) ) { close( fd ); return (size_t)0L; /* Can't read? */ } close( fd ); return (size_t)(psinfo.pr_rssize * 1024L); #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) /* BSD, Linux, and OSX -------------------------------------- */ struct rusage rusage; getrusage( RUSAGE_SELF, &rusage ); #if defined(__APPLE__) && defined(__MACH__) return (size_t)rusage.ru_maxrss; #else return (size_t)(rusage.ru_maxrss * 1024L); #endif #else /* Unknown OS ----------------------------------------------- */ return (size_t)0L; /* Unsupported. */ #endif } /** * Returns the current resident set size (physical memory use) measured * in bytes, or zero if the value cannot be determined on this OS. */ size_t getCurrentRSS( ) { #if defined(_WIN32) /* Windows -------------------------------------------------- */ PROCESS_MEMORY_COUNTERS info; GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); return (size_t)info.WorkingSetSize; #elif defined(__APPLE__) && defined(__MACH__) /* OSX ------------------------------------------------------ */ struct mach_task_basic_info info; mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount ) != KERN_SUCCESS ) return (size_t)0L; /* Can't access? */ return (size_t)info.resident_size; #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) /* Linux ---------------------------------------------------- */ long rss = 0L; FILE* fp = NULL; if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL ) return (size_t)0L; /* Can't open? */ if ( fscanf( fp, "%*s%ld", &rss ) != 1 ) { fclose( fp ); return (size_t)0L; /* Can't read? */ } fclose( fp ); return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE); #else /* AIX, BSD, Solaris, and Unknown OS ------------------------ */ return (size_t)0L; /* Unsupported. */ #endif }
Применение
size_t currentSize = getCurrentRSS( ); size_t peakSize = getPeakRSS( );
Для более подробного обсуждения посетите веб-сайт, он также предоставляет функцию для получения размера физической памяти системы .
источник
#pragma comment(lib, "psapi.lib")
в#if defined(_WIN32)
сферу.Старый:
Новое: похоже, что вышесказанное на самом деле не работает, поскольку ядро не заполняет большинство значений. Что действительно работает, так это получить информацию от proc. Однако, вместо того, чтобы разбираться самостоятельно, проще использовать libproc (часть procps) следующим образом:
// getrusage.c #include <stdio.h> #include <proc/readproc.h> int main() { struct proc_t usage; look_up_our_self(&usage); printf("usage: %lu\n", usage.vsize); }
Скомпилировать с "
gcc -o getrusage getrusage.c -lproc
"источник
#include <proc/readproc.h>
Решение работало большое для меня под Ubuntu. Пришлось установить пакетlibproc-dev
.usage.vm_data
достаточно близко к тому, что мне нужно. Ваш выбор статистики памяти задокументирован здесь: все/usr/include/proc/readproc.h
те, которые я пробовал, кажутся байтами, а не страницами. Я не думаю, что в моем процессе использовалось 46 миллионов страниц. Комментарии о том, что это решение не работает под Linux, кажутся ошибочными.В linux, если вы можете позволить себе стоимость времени выполнения (для отладки), вы можете использовать valgrind с инструментом massif:
http://valgrind.org/docs/manual/ms-manual.html
Это большой вес, но очень полезный.
источник
Более элегантный способ для метода Дона Уэйкфилда:
#include <iostream> #include <fstream> using namespace std; int main(){ int tSize = 0, resident = 0, share = 0; ifstream buffer("/proc/self/statm"); buffer >> tSize >> resident >> share; buffer.close(); long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages double rss = resident * page_size_kb; cout << "RSS - " << rss << " kB\n"; double shared_mem = share * page_size_kb; cout << "Shared Memory - " << shared_mem << " kB\n"; cout << "Private Memory - " << rss - shared_mem << "kB\n"; return 0; }
источник
Существующие ответы лучше подходят для получения правильного значения, но я могу по крайней мере объяснить, почему getrusage не работает для вас.
мужчина 2 получает:
источник
в дополнение к вашему способу
вы можете вызвать команду system ps и получить данные об использовании памяти.
или прочтите информацию из / proc / pid (см. структуру PIOCPSINFO)
источник
В вашей системе есть файл с именем
/proc/self/statm
. Файловая система proc - это псевдофайловая система, которая предоставляет интерфейс для структур данных ядра. Этот файл содержит необходимую информацию в столбцах, где только целые числа разделены пробелами.Номер столбца:
= общий размер программы (VmSize в / proc / [pid] / status)
= размер резидентного набора (VmRSS в / proc / [pid] / status)
Для получения дополнительной информации см. ССЫЛКУ .
источник
Я использую другой способ сделать это, и это звучит реалистично. Я получил PID процесса с помощью функции getpid (), а затем использую файл / proc / pid / stat. Я считаю, что 23-й столбец стат-файла - это размер vmsize (см. Сообщение Дона). Вы можете прочитать vmsize из файла в любом месте кода. Если вам интересно, сколько фрагмента кода может использовать память, вы можете прочитать этот файл один раз перед этим фрагментом и один раз после него, и вы можете вычесть их друг из друга.
источник
На основе решения Дона В. с меньшим количеством переменных.
void process_mem_usage(double& vm_usage, double& resident_set) { vm_usage = 0.0; resident_set = 0.0; // the two fields we want unsigned long vsize; long rss; { std::string ignore; std::ifstream ifs("/proc/self/stat", std::ios_base::in); ifs >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> vsize >> rss; } long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages vm_usage = vsize / 1024.0; resident_set = rss * page_size_kb; }
источник
Я искал приложение для Linux для измерения максимального объема используемой памяти. valgrind - отличный инструмент, но он дал мне больше информации, чем я хотел. tstime казался лучшим инструментом, который я мог найти. Он измеряет использование оперативной памяти (RSS и виртуальной). Смотрите этот ответ .
источник