Como obter o uso de memory em tempo de execução usando C ++?

Eu preciso obter o mem uso VIRT e RES no tempo de execução do meu programa e exibi-los.

O que eu tentei até agora:

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; 

mas eu sempre recebo 0.

   

No Linux, nunca encontrei uma solução ioctl () . Para nossas aplicações, codificamos uma rotina de utilitário geral baseada na leitura de arquivos em / proc / pid . Existem vários desses arquivos que fornecem resultados diferentes. Aqui está o que decidimos (a questão foi marcada com C ++, e nós lidamos com E / S usando construções C ++, mas ela deve ser facilmente adaptável a rotinas de C i / o se você precisar):

 #include  #include  #include  #include  #include  ////////////////////////////////////////////////////////////////////////////// // // 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; } 

David Robert Nadeau colocou uma boa function C multi-plataforma contida para obter o tamanho do conjunto residente do processo (uso da memory física) em seu site:

 /* * 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  #include  #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) #include  #include  #if defined(__APPLE__) && defined(__MACH__) #include  #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) #include  #include  #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) #include  #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 } 

Uso

 size_t currentSize = getCurrentRSS( ); size_t peakSize = getPeakRSS( ); 

Para mais discussão, verifique o site, ele também fornece uma function para obter o tamanho da memory física de um sistema .

Velho:

O maxrss indica a memory máxima disponível para o processo. 0 significa que nenhum limite é colocado no processo. O que você provavelmente quer é o uso não compartilhado de dados ru_idrss .

Novo: Parece que o acima não funciona, pois o kernel não preenche a maioria dos valores. O que funciona é obter as informações do proc. Em vez de analisá-lo, é mais fácil usar o libproc (parte do procps) da seguinte maneira:

 // getrusage.c #include  #include  int main() { struct proc_t usage; look_up_our_self(&usage); printf("usage: %lu\n", usage.vsize); } 

Compile com ” gcc -o getrusage getrusage.c -lproc

No linux, se você puder pagar o custo do tempo de execução (para debugging), você pode usar o valgrind com a ferramenta massif:

http://valgrind.org/docs/manual/ms-manual.html

É pesado, mas muito útil.

As respostas existentes são melhores para saber como obter o valor correto, mas posso pelo menos explicar por que o getrusage não está funcionando para você.

homem 2 getrusage:

A estrutura [rusage] acima foi tirada de BSD 4.3 Reno. Nem todos os campos são significativos no Linux. No momento (Linux 2.4, 2.6) apenas os campos ru_utime, ru_stime, ru_minflt, ru_majflt e ru_nswap são mantidos.

Uma maneira mais elegante para o método Don Wakefield:

 #include  #include  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; } 

em adicional ao seu caminho
você poderia chamar o comando system ps e obter o uso de memory da saída.
ou ler informações de / proc / pid (consulte Estrutura PIOCPSINFO)

Eu estou usando outra maneira de fazer isso e parece realista. O que eu faço é obter o PID do processo pela function getpid () e depois uso o arquivo / proc / pid / stat. Eu acredito que a coluna 23 do arquivo de statistics é o vmsize (veja o post Don). Você pode ler o vmsize do arquivo onde quer que você precise no código. Caso você queira saber quanto um snippet de um código pode usar memory, você pode ler esse arquivo uma vez antes desse snippet e uma vez depois e você pode subtraí-los um do outro.

Baseado na solução de Don W, com menos variables.

 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; } 

Eu estava procurando por um aplicativo Linux para medir a memory máxima usada. Valgrind é uma excelente ferramenta, mas estava me dando mais informações do que eu queria. tstime parecia ser a melhor ferramenta que eu poderia encontrar. Ele mede o uso de memory “highwater” (RSS e virtual). Veja esta resposta .