I would like to measure the peak memory consumption of a program with a running time too short for top. Normally, time should do the job. But on my Debian Sarge system it does not:
Code:
> /usr/bin/time <program> <args>
<program output>
2.06user 0.92system 0:03.03elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (174major+1874minor)pagefaults 0swaps
(note the usage of /usr/bin/time to avoid bash's built-in time command)
As you see maxresident is 0 which is obviously wrong as my program consumes awesome lot of memory. This is the case for all other programs I try. The man page for time states that zero values may indicate your Unix flavor does not support their measurement. This is not true for Linux in general I suppose. So why on earth does it not work for me?
All this could be reduced to the wait4 or getrusage system call. I have written a little replacement for time:
(rusage.c)
Code:
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char** argv, char** envp) {
int pid, err, ret;
struct rusage usage;
if((pid = fork()) == 0) {
if (execve(argv[0],++argv,envp) == -1) perror("Error during execve: ");
}
else {
if(wait4(pid,&ret,0,&usage) == -1) perror("Error during wait4: ");
else {
printf("\n");
printf(" maximum resident size: %ld\n",usage.ru_maxrss);
}
}
return ret;
}
wait4 puts the process statistics for the child process into the structure usage. Its field ru_maxrss then should contain the maximum resident size. But here is my output:
Code:
> gcc -o rusage rusage.c
> ./rusage <program> <args>
<program output>
maximum resident size: 0
I have found out that all process monitoring programs except time use the /proc pseudo-fs to gather their information. Thus one needs to constantly monitor /proc/<pid>/stat to get the peak memory consumption. This is not very elegant in my opinion, as the program does not run for very long, so very small time intervals are needed.
Is there perhaps another, better way to do it?
for the sake of completeness:
Debian Sarge with kernel version 2.4.27-2-686
Manpages: getrusage (2), time (1), proc (5)