Memory usage of current process in C
Solution 1
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.
Solution 2
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)
Solution 3
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)
Solution 4
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)
Solution 5
#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()
scotts
Updated on December 06, 2021Comments
-
scotts over 2 years
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.
-
scotts over 14 yearsUnfortunately the ru_idrss and ru_isrss data isn't availabe to my kernel (Ubuntu Hardy): linux.die.net/man/2/getrusage
-
James over 12 yearsThat's because, even in version 2.6, 10 years after POSIX.1, Linux still doesn't implement getrusage() except for a few fields. :-( Apparently, the only way to get the information is through kernel calls or reading /proc/<pid>/statm (see man 5 proc), which is completely unportable.
-
Not a Name over 11 yearsWhy are you using malloc for a statically sized struct?
-
Achim about 7 yearsUnfortunately all data is showing 0 on my kernel (Debian Wheezy)
-
Achim about 7 yearsUnfortunately also ru_maxrss is always showing 0 on my kernel (Debian Wheezy)
-
avl_sweden over 6 yearsThis seems to work on Linux 4.12.4 at least. Although I wonder if maybe it's actually returning kilobytes.
-
Anti Earth over 6 yearsCaution; I don't handle when
file
doesn't exist -
Matthieu M. over 5 yearsThe problem with this method is the measured in pages bit. If your process uses three 4kB pages, two 2MB pages and one 1GB page, it reports that 6 pages are used. Technically correct, but utterly useless to deduce the RSS in bytes.
-
Ciro Santilli OurBigBook.com over 4 years@MatthieuM.
man proc
also ways that "/proc/[pid]/status
Provides much of the information in/proc/[pid]/stat
and/proc/[pid]/statm
", and that stat is used byps
, which then implies that both/proc/self/status
andps
itself also share this problem, is that your understanding? Can you also cite something that shows that a single process can have pages of multiple different sizes? Thanks! -
Matthieu M. over 4 years@CiroSantilli新疆改造中心996ICU六四事件: I can only cite my own experience using manual huge pages + regular pages.
-
Ciro Santilli OurBigBook.com over 4 years@MatthieuM. thanks, I didn't know about
mmap
MAP_HUGE*
:-) This is sad. -
Ciro Santilli OurBigBook.com over 4 yearsOne may also be tempted to parse
/proc/self/stat
which contains just numbers without labels, and according toman proc
is used byps
. Orstatm
which is astat
subset for memory: stackoverflow.com/a/7212248/895245 Matthieu mentions that all those may be wrong for huge pages though: stackoverflow.com/questions/1558402/… I have to test it out. -
mwag over 4 yearsshouldn't
int *
beint
and fscanf args be e.g.&currRealMem
instead ofcurrRealMem
??? -
Anti Earth over 4 years@mwag No, this function "returns" by modifying the referenced primitives. You want to pass references of the caller primitives to this function. E.g.
int a, b, c, d; getMemory(&a, &b, &c, &d);
-
mwag over 4 yearsmy bad, misread those
int*
s as being local vars rather than function args. -
SRG over 4 yearsCan you use
&
in C? I thought that was a C++ feature, isn't it? I mean, the function should accept astatm_t *result
pointer instead. Am I missing something? -
James over 4 years&x is original C and means "the address pointing to the variable x". In C++, somewhat confusingly, the same character is used in type declarations to denote references.
-
GroovyDotCom almost 3 yearsNote that fopen of /proc/self/status can fail intermittently so check