2009-10-13 22 views
16

Necesito obtener el uso de memoria del proceso actual en C. ¿Alguien puede ofrecer una muestra de código de cómo hacerlo en una plataforma Linux?Uso de memoria del proceso actual en C

estoy consciente del método de conseguir el uso de memoria cat /proc/<your pid>/status, pero no tengo ni idea de cómo capturar que en C.

Por cierto, es una extensión de PHP que estoy modificando (concedido, soy un C novato). Si hay accesos directos disponibles dentro de la API de extensión de PHP, eso sería aún más útil.

Respuesta

23

siempre puede abrir los archivos '' en el sistema a medida que /proc sería un archivo normal (usando el enlace simbólico 'auto' por lo que no tiene que buscar su propia PID):

FILE* status = fopen("/proc/self/status", "r"); 

Por supuesto, ahora tiene que analizar el archivo de seleccionar la información que necesita.

22

La función de biblioteca getrusage devuelve una estructura que contiene una gran cantidad de datos sobre el proceso actual, incluyendo los siguientes:

long ru_ixrss;   /* integral shared memory size */ 
long ru_idrss;   /* integral unshared data size */ 
long ru_isrss;   /* integral unshared stack size */ 

Sin embargo, la documentación de Linux más arriba-hasta la fecha dice acerca de estos 3 campos

(unmaintained) This field is currently unused on Linux 

Ver getrusage(2)

+2

Desafortunadamente los datos ru_idrss y ru_isrss no se halla disponible a mi kernel (Ubuntu Hardy): http://linux.die.net/man/2/getrusage – scotts

+0

Por desgracia todos los datos se muestran 0 en mi kernel (Debian Wheezy) – Achim

6
#include <sys/resource.h> 
#include <errno.h> 

errno = 0; 
struct rusage* memory = malloc(sizeof(struct rusage)); 
getrusage(RUSAGE_SELF, memory); 
if(errno == EFAULT) 
    printf("Error: EFAULT\n"); 
else if(errno == EINVAL) 
    printf("Error: EINVAL\n"); 
printf("Usage: %ld\n", memory->ru_ixrss); 
printf("Usage: %ld\n", memory->ru_isrss); 
printf("Usage: %ld\n", memory->ru_idrss); 
printf("Max: %ld\n", memory->ru_maxrss); 

que utiliza este código, pero por alguna razón me 0 todo el tiempo para todos 4 printf()

+7

Esto se debe a que, incluso en la versión 2.6, 10 años después de POSIX.1, Linux aún no implementa getrusage() a excepción de unos pocos campos. :-(Aparentemente, la única forma de obtener la información es a través de llamadas al núcleo o leyendo/proc//statm (ver man 5 proc), que es completamente imposible de transportar. – James

+4

¿Por qué está utilizando malloc para una estructura de tamaño estático? –

0

La estructura anterior fue tomado de BSD 4.3 Reno. No todos los campos son malos en Linux. En linux 2.4 solo se mantienen los campos ru_utime, ru_stime, ru_minflt y ru_majflt. Desde Linux 2.6, ru_nvcsw y ru_nivcsw también se mantienen.

http://www.atarininja.org/index.py/tags/code

13

Esta es una manera terriblemente feo y no portátiles de conseguir el uso de la memoria, pero desde getrusage() 's de seguimiento de memoria es esencialmente inútil en Linux, la lectura/proc // statm es la única manera Sé de obtener la información sobre Linux.

Si alguien sabe de una manera más limpia, o preferiblemente más transversal entre Unix de seguimiento de uso de memoria, estaría muy interesado en aprender cómo hacerlo.

typedef struct { 
    unsigned long size,resident,share,text,lib,data,dt; 
} statm_t; 

void read_off_memory_status(statm_t& result) 
{ 
    unsigned long dummy; 
    const char* statm_path = "/proc/self/statm"; 

    FILE *f = fopen(statm_path,"r"); 
    if(!f){ 
    perror(statm_path); 
    abort(); 
    } 
    if(7 != fscanf(f,"%ld %ld %ld %ld %ld %ld %ld", 
    &result.size,&result.resident,&result.share,&result.text,&result.lib,&result.data,&result.dt)) 
    { 
    perror(statm_path); 
    abort(); 
    } 
    fclose(f); 
} 

Desde el proc (5) página de manual:

/proc/[pid]/statm 
      Provides information about memory usage, measured in pages. 
      The columns are: 

       size  total program size 
         (same as VmSize in /proc/[pid]/status) 
       resident resident set size 
         (same as VmRSS in /proc/[pid]/status) 
       share  shared pages (from shared mappings) 
       text  text (code) 
       lib  library (unused in Linux 2.6) 
       data  data + stack 
       dt   dirty pages (unused in Linux 2.6) 
4

me encontré con este post: http://appcrawler.com/wordpress/2013/05/13/simple-example-of-tracking-memory-using-getrusage/

versión simplificada:

#include <sys/resource.h> 
#include <stdio.h> 

int main() { 
    struct rusage r_usage; 
    getrusage(RUSAGE_SELF,&r_usage); 
    // Print the maximum resident set size used (in kilobytes). 
    printf("Memory usage: %ld kilobytes\n",r_usage.ru_maxrss); 
    return 0; 
} 

(probado en Linux 3.13)

+0

Desafortunadamente también ru_maxrss siempre muestra 0 en mi kernel (Debian Wheezy) – Achim

+0

Esto parece funcionar en Linux 4.12.4 como mínimo. Aunque me pregunto si en realidad está devolviendo kilobytes. –

1

Estoy llegar tarde a la fiesta, pero esto podría ser útil para cualquier otra persona que esté buscando recuerdos residentes y virtuales (y sus valores máximos hasta ahora) en Linux.

Probablemente sea bastante terrible, pero hace el trabajo bien.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 


/* 
* Measures the current (and peak) resident and virtual memories 
* usage of your linux C process, in kB 
*/ 
void getMemory(
    int* currRealMem, int* peakRealMem, 
    int* currVirtMem, int* peakVirtMem) { 

    // stores each word in status file 
    char buffer[1024] = ""; 

    // linux file contains this-process info 
    FILE* file = fopen("/proc/self/status", "r"); 

    // read the entire file 
    while (fscanf(file, " %1023s", buffer) == 1) { 

     if (strcmp(buffer, "VmRSS:") == 0) { 
      fscanf(file, " %d", currRealMem); 
     } 
     if (strcmp(buffer, "VmHWM:") == 0) { 
      fscanf(file, " %d", peakRealMem); 
     } 
     if (strcmp(buffer, "VmSize:") == 0) { 
      fscanf(file, " %d", currVirtMem); 
     } 
     if (strcmp(buffer, "VmPeak:") == 0) { 
      fscanf(file, " %d", peakVirtMem); 
     } 
    } 
    fclose(file); 
} 
+0

Atención: No manejo cuando 'file' doesn ' t existir –

Cuestiones relacionadas