Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory usage of current process in C

I need to get the memory usage of the current process in C. Can someone offer a code sample of how to do this on a Linux platform?

I'm aware of the cat /proc/<your pid>/status method of getting memory usage, but I have no idea how to capture that in C.

BTW, it's for a PHP extension I'm modifying (granted, I'm a C newbie). If there are shortcuts available within the PHP extension API, that would be even more helpful.

like image 473
scotts Avatar asked Oct 13 '09 05:10

scotts


People also ask

How do I see how much memory a process is using?

In the Activity Monitor utility, you can see the name of each process running ("Process Name" column) and how much memory each process is using ("Real Mem" column).

How much memory is my program using?

Run the program in one shell. Open another shell and run 'top' command. it will list running processes and home much memory they consume. you can, i guess, poll /proc/yourprocessid/stat to see how much memory it is using over time.

How do I check my top memory usage?

You can also filter processes by memory usage in top. To do this, press SHIFT + m as shown: Top will filter the processes by memory usage in descending order. Doing this can help identify the process using the most memory, giving you a chance to take action.


6 Answers

The getrusage library function returns a structure containing a whole lot of data about the current process, including these:

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

However, the most up-to-date linux documentation says about these 3 fields

(unmaintained) This field is currently unused on Linux

which the manual then defines as:

Not all fields are completed; unmaintained fields are set to zero by the kernel. (The unmaintained fields are provided for compatibility with other systems, and because they may one day be supported on Linux.)

See getrusage(2)

like image 133
caf Avatar answered Sep 20 '22 17:09

caf


You can always just open the 'files' in the /proc system as you would a regular file (using the 'self' symlink so you don't have to look up your own pid):

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

Of course, you now have to parse the file to pick out the information you need.

like image 38
CB Bailey Avatar answered Sep 24 '22 17:09

CB Bailey


This is a terribly ugly and non-portable way of getting the memory usage, but since getrusage()'s memory tracking is essentially useless on Linux, reading /proc/<pid>/statm is the only way I know of to get the information on Linux.

If anyone know of cleaner, or preferably more cross-Unix ways of tracking memory usage, I would be very interested in learning how.

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

From the proc(5) man-page:

   /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)
like image 36
James Avatar answered Sep 20 '22 17:09

James


I came across this post: http://appcrawler.com/wordpress/2013/05/13/simple-example-of-tracking-memory-using-getrusage/

Simplified version:

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

(tested in Linux 3.13)

like image 34
lepe Avatar answered Sep 23 '22 17:09

lepe


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

errno = 0;
struct rusage memory;
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);

I used this code but for some reason I get 0 all the time for all 4 printf()

like image 35
Jeff Avatar answered Sep 21 '22 17:09

Jeff


I'm late to the party, but this might be helpful for anyone else looking for the resident and virtual (and their peak values so far) memories on linux.

It's probably pretty terrible, but it gets the job done.

#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);
}
like image 32
Anti Earth Avatar answered Sep 23 '22 17:09

Anti Earth