2009-10-13 8 views
16

J'ai besoin d'obtenir l'utilisation de la mémoire du processus actuel en C. Quelqu'un peut-il offrir un exemple de code sur la façon de faire cela sur une plate-forme Linux?Utilisation de la mémoire du processus en cours dans C

Je suis au courant de la méthode cat /proc/<your pid>/status d'obtenir l'utilisation de la mémoire, mais je ne sais pas comment capturer que C.

BTW, il est une extension de PHP je modifier (accordée, je suis un débutant C). S'il y a des raccourcis disponibles dans l'API d'extension PHP, ce serait encore plus utile.

Répondre

23

vous pouvez toujours ouvrir les fichiers « » dans le système /proc que vous serait un fichier régulier (en utilisant le lien symbolique « auto » de sorte que vous ne devez pas regarder votre propre pid):

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

Bien sûr, vous avez maintenant d'analyser le fichier pour choisir les informations dont vous avez besoin.

22

La getrusage fonction bibliothèque renvoie une structure contenant beaucoup de données sur le processus en cours, y compris ceux-ci:

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

Cependant, la plus à jour la documentation linux dit au sujet de ces 3 champs

(unmaintained) This field is currently unused on Linux 

Voir getrusage(2)

+2

Malheureusement, le ru_idrss et les données ru_isrss n'est pas Availabe à mon noyau (Ubuntu Hardy): http://linux.die.net/man/2/getrusage – scotts

+0

Malheureusement toutes les données montre 0 sur mon noyau (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); 

J'ai utilisé ce code, mais pour une raison quelconque je reçois 0 tout le temps pour les 4 printf()

+7

En effet, même dans la version 2.6, 10 ans après POSIX.1, Linux n'implémente toujours pas getrusage() à l'exception de quelques champs. :-(Apparemment, la seule façon d'obtenir l'information est à travers les appels du noyau ou en lisant/proc//statm (voir man 5 proc), qui est complètement nonportable – James

+4

Pourquoi utilisez-vous malloc pour une structure de taille statique? –

0

Le struct ci-dessus a été prise de 4.3BSD Reno. Tous les champs ne sont pas méchants sous Linux. Dans linux 2.4, seuls les champs ru_utime, ru_stime, ru_minflt et ru_majflt sont conservés. Depuis Linux 2.6, ru_nvcsw et ru_nivcsw sont également maintenus.

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

13

C'est une façon terriblement laid et non portable d'obtenir l'utilisation de la mémoire, mais comme le suivi de la mémoire de getrusage() est essentiellement inutile sur Linux, lecture/proc // statm est la seule façon Je sais d'obtenir l'information sur Linux.

Si quelqu'un connaît des méthodes Unix plus propres, ou de préférence plus croisées, pour suivre l'utilisation de la mémoire, je serais très intéressé à apprendre comment.

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

De la proc (5) page man:

/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

je suis tombé sur ce poste: http://appcrawler.com/wordpress/2013/05/13/simple-example-of-tracking-memory-using-getrusage/

Version simplifiée:

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

(testé sous Linux 3.13

+0

Malheureusement aussi ru_maxrss montre toujours 0 sur mon noyau (Debian Wheezy) – Achim

+0

Cela semble fonctionner sur Linux 4.12.4 au moins, même si je me demande si c'est peut-être un retour de kilo-octets –

1

Je suis en retard à la fête, mais cela pourrait être utile pour quelqu'un d'autre à la recherche du résident et virtuel (et leurs valeurs de pointe jusqu'à présent) des souvenirs sur Linux.

C'est probablement très horrible, mais ça fait l'affaire.

#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

Attention, je ne gère pas quand 'file' doesn ' T exister –

Questions connexes