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.
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).
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.
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.
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)
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.
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)
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)
#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()
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With