Preciso obter o VIRT e RES do uso do mem em 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 sempre recebo 0.
Respostas:
No Linux, nunca encontrei uma solução ioctl () . Para nossos aplicativos, codificamos uma rotina de utilitário geral baseada na leitura de arquivos em / proc / pid . Existem vários desses arquivos que apresentam resultados diferentes. Aqui está o que decidimos (a questão foi marcada como C ++, e lidamos com I / O usando construções C ++, mas deve ser facilmente adaptável a rotinas C i / o se você precisar):
#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; }
fonte
why 1024.0?
- Diz ao compilador para converter para double FIRST e então fazer a divisão para obter o resultado duplo. A outra escolha:vm_usage = vsize / 1024;
faria a divisão primeiro (perdendo a precisão como @DonWakefield sugeriu) e depois converteria para o dobro.David Robert Nadeau colocou uma boa função C multi-plataforma independente para obter o tamanho do conjunto residente do processo (uso de memória 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 <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 }
Uso
size_t currentSize = getCurrentRSS( ); size_t peakSize = getPeakRSS( );
Para mais discussão, verifique o site, ele também fornece uma função para obter o tamanho da memória física de um sistema .
fonte
#pragma comment(lib, "psapi.lib")
ao#if defined(_WIN32)
escopo.Velho:
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 sozinho, é mais fácil usar libproc (parte do procps) da seguinte maneira:
// 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); }
Compilar com "
gcc -o getrusage getrusage.c -lproc
"fonte
#include <proc/readproc.h>
solução funcionou muito bem para mim no Ubuntu. Tive que instalar o pacotelibproc-dev
.usage.vm_data
é uma aproximação suficiente do que eu precisava. Sua escolha de estatística de memória está documentada aqui:/usr/include/proc/readproc.h
Todos os que tentei parecem estar em bytes, não em páginas. Não acho que meu processo estava usando 46 milhões de páginas. Os comentários de que esta solução não funciona no Linux parecem equivocados.No Linux, se você pode pagar o custo de tempo de execução (para depuração), você pode usar valgrind com a ferramenta massif:
http://valgrind.org/docs/manual/ms-manual.html
É pesado, mas muito útil.
fonte
Uma maneira mais elegante para o método Don Wakefield:
#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; }
fonte
As respostas existentes são melhores para saber como obter o valor correto, mas posso pelo menos explicar por que getrusage não está funcionando para você.
man 2 getrusage:
fonte
além da sua maneira,
você pode chamar o comando system ps e obter o uso de memória de sua saída.
ou leia as informações em / proc / pid (consulte a estrutura PIOCPSINFO)
fonte
No seu sistema existe um arquivo chamado
/proc/self/statm
. O sistema de arquivos proc é um pseudo-sistema de arquivos que fornece uma interface para as estruturas de dados do kernel. Este arquivo contém as informações de que você precisa em colunas apenas com números inteiros separados por espaço.Número da coluna:
= tamanho total do programa (VmSize em / proc / [pid] / status)
= tamanho do conjunto residente (VmRSS em / proc / [pid] / status)
Para obter mais informações, consulte o LINK .
fonte
Estou usando outra maneira de fazer isso e parece realista. O que eu faço é obter o PID do processo pela função getpid () e usar o arquivo / proc / pid / stat. Eu acredito que a 23ª coluna do arquivo stat é o vmsize (veja o post de Don). Você pode ler o vmsize do arquivo sempre que precisar no código. Caso você esteja se perguntando quanto um trecho de código pode usar a memória, você pode ler esse arquivo uma vez antes do trecho e uma vez depois e pode subtraí-los um do outro.
fonte
Baseado na solução de Don W, com menos variáveis.
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; }
fonte
Eu estava procurando um aplicativo Linux para medir a memória máxima usada. valgrind é uma ferramenta excelente, mas estava me dando mais informações do que eu queria. O tempo parecia ser a melhor ferramenta que pude encontrar. Ele mede o uso de memória "highwater" (RSS e virtual). Veja esta resposta .
fonte