Использование памяти текущего процесса в C - PullRequest
20 голосов
/ 13 октября 2009

Мне нужно получить использование памяти текущего процесса в C. Может ли кто-нибудь предложить пример кода, как это сделать на платформе Linux?

Я знаю о cat /proc/<your pid>/status методе использования памяти, но я не знаю, как зафиксировать это в C.

Кстати, это расширение PHP, которое я модифицирую (да, я новичок в C). Если бы в API расширений PHP были доступны ярлыки, это было бы еще более полезно.

Ответы [ 7 ]

26 голосов
/ 13 октября 2009

Вы всегда можете просто открыть «файлы» в системе /proc, как обычный файл (используя символическую ссылку «self», чтобы вам не приходилось искать свой собственный pid):

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

Конечно, теперь вам нужно проанализировать файл, чтобы выбрать необходимую информацию.

25 голосов
/ 13 октября 2009

Библиотечная функция getrusage возвращает структуру, содержащую множество данных о текущем процессе, включая следующие:

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

Однако в самой современной документации linux говорится об этих 3 полях

(unmaintained) This field is currently unused on Linux

См. getrusage (2)

13 голосов
/ 27 августа 2011

Это ужасно уродливый и непереносимый способ получения использования памяти, но так как отслеживание памяти getrusage () в Linux практически бесполезно, чтение / proc // statm - единственный известный мне способ получить информация о Linux.

Если кто-нибудь знает более чистые или, желательно, более кросс-Unix способы отслеживания использования памяти, мне было бы очень интересно узнать, как это сделать.

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

Из man-страницы proc (5):

   /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)
7 голосов
/ 19 декабря 2009
#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);

Я использовал этот код, но по какой-то причине я все время получаю 0 для всех 4 printf ()

6 голосов
/ 06 июля 2015

Я наткнулся на этот пост: http://appcrawler.com/wordpress/2013/05/13/simple-example-of-tracking-memory-using-getrusage/

Упрощенная версия:

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

(протестировано в Linux 3.13)

4 голосов
/ 28 ноября 2017

Я опаздываю на вечеринку, но это может быть полезно для всех, кто ищет резидентные и виртуальные (и их пиковые значения) воспоминания о linux.

Это, наверное, довольно ужасно, но это делает работу.

#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 голосов
/ 19 апреля 2010

Приведенная выше структура была взята из 4.3BSD Reno. Не все поля являются средними под Linux. В Linux 2.4 только поля ru_utime, ru_stime, ru_minflt и ru_majflt поддерживаются. Начиная с Linux 2.6, ru_nvcsw и ru_nivcsw также поддерживаются.

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

...