Necesito obtener el uso de mem VIRT y RES en tiempo de ejecución de mi programa y mostrarlos.
Lo que intenté hasta ahora:
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;
pero siempre obtengo 0.
Respuestas:
En Linux, nunca encontré una solución ioctl () . Para nuestras aplicaciones, codificamos una rutina de utilidad general basada en la lectura de archivos en / proc / pid . Hay varios de estos archivos que dan resultados diferentes. Aquí está el que decidimos (la pregunta estaba etiquetada como C ++, y manejamos la E / S usando construcciones de C ++, pero debería ser fácilmente adaptable a las rutinas de C i / o si es necesario):
#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; }
fuente
why 1024.0?
- Le dice al compilador que convierta a doble PRIMERO y luego haga la división para obtener el resultado doble. La otra opción:vm_usage = vsize / 1024;
haría la división primero (perdiendo precisión como sugirió @DonWakefield) y luego convertiría a doble.David Robert Nadeau ha puesto una buena función C multiplataforma autónoma para obtener el tamaño del conjunto residente del proceso (uso de memoria física) en su sitio web:
/* * 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 obtener más información, consulte el sitio web, también proporciona una función para obtener el tamaño de la memoria física de un sistema .
fuente
#pragma comment(lib, "psapi.lib")
el#if defined(_WIN32)
alcance.Antiguo:
Nuevo: Parece que lo anterior en realidad no funciona, ya que el kernel no llena la mayoría de los valores. Lo que sí funciona es obtener la información de proc. Sin embargo, en lugar de analizarlo uno mismo, es más fácil usar libproc (parte de procps) de la siguiente manera:
// 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 con "
gcc -o getrusage getrusage.c -lproc
"fuente
#include <proc/readproc.h>
solución funcionó muy bien para mí en Ubuntu. Tuve que instalar el paquetelibproc-dev
.usage.vm_data
es una aproximación lo suficientemente cercana a lo que necesitaba. Su elección de estadística de memoria se documenta aquí:/usr/include/proc/readproc.h
Las que probé parecen estar en bytes, no en páginas. No creo que mi proceso usara 46 millones de páginas. Los comentarios de que esta solución no funciona en Linux parecen equivocados.En Linux, si puede pagar el costo del tiempo de ejecución (para la depuración), puede usar valgrind con la herramienta massif:
http://valgrind.org/docs/manual/ms-manual.html
Es pesado, pero muy útil.
fuente
Una forma más elegante para el 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; }
fuente
Las respuestas existentes son mejores sobre cómo obtener el valor correcto, pero al menos puedo explicar por qué getrusage no funciona para usted.
hombre 2 getrusage:
fuente
Además de su forma
, puede llamar al comando system ps y obtener el uso de memoria de su salida.
o leer información de / proc / pid (ver estructura PIOCPSINFO)
fuente
En su sistema hay un archivo llamado
/proc/self/statm
. El sistema de archivos proc es un pseudo-sistema de archivos que proporciona una interfaz para las estructuras de datos del kernel. Este archivo contiene la información que necesita en columnas con solo números enteros separados por espacios.No de columna:
= tamaño total del programa (VmSize en / proc / [pid] / status)
= tamaño del conjunto residente (VmRSS en / proc / [pid] / status)
Para obtener más información, consulte el ENLACE .
fuente
Estoy usando otra forma de hacerlo y suena realista. Lo que hago es obtener el PID del proceso mediante la función getpid () y luego uso el archivo / proc / pid / stat. Creo que la columna 23 del archivo de estadísticas es vmsize (mira la publicación de Don). Puede leer el vmsize del archivo donde lo necesite en el código. En caso de que se pregunte cuánto puede usar la memoria un fragmento de código, puede leer ese archivo una vez antes de ese fragmento y una vez después y puede restarlos entre sí.
fuente
Basado en la solución de Don W, con 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; }
fuente
Estaba buscando una aplicación de Linux para medir la memoria máxima utilizada. valgrind es una herramienta excelente, pero me estaba dando más información de la que quería. La época parecía ser la mejor herramienta que pude encontrar. Mide el uso de memoria "de aguas altas" (RSS y virtual). Vea esta respuesta .
fuente