Recently, I was faced with a peculiar application performance problem on Linux due to memory allocator inefficiencies. Part of the investigation mandated that I had to figure out what was the application's memory allocation pattern.
Using DTrace on Solaris 10 was the quickest and best choice possible. Within a few minutes, I was able to write a simple script that allowed me to monitor calls to memory allocation functions malloc, calloc, realloc and free.
Below is the script. Simple function entry and return probes along with aggregation functions and timer probes assembled in less than 50 lines of code did the trick.
Just imagine having to write this in C ... besides the code is meant to be disposed after the investigation, so it's the kind of situation where DTrace comes to the rescue.
I am impatiently waiting for SystemTAP (DTrace's equivalent on Linux) to support userland probes because it would allow me to do this kind of observations and investigations natively on Linux without having to resort to using Solaris 10/DTrace.
Till then, I consider DTrace to be the coolest technology Sun has introduced in Solaris 10.
#!/usr/sbin/dtrace -s
BEGIN
{
malloc = 0;
calloc = 0;
realloc = 0;
free = 0;
malloctime = 0;
printf("| timestamp | malloc | calloc | realloc | free | avg malloc duration |");
}
pid$target::malloc:entry
{
@["malloc"] = quantize(arg0);
malloc += 1;
last = timestamp;
}
pid$target::malloc:return
{
malloctime += (timestamp - last);
}
pid$target::calloc:entry
{
@["calloc"] = quantize(arg0*arg1);
calloc +=1;
}
pid$target::realloc:entry
{
@["realloc"] = quantize(arg1);
realloc += 1;
}
pid$target::free:entry
{
free += 1;
}
tick-60sec
{
avgmalloctime = malloctime/malloc;
printf("| %Y | %12d | %12d | %12d | %12d | %12d |", walltimestamp, malloc, calloc, realloc, free, avgmalloctime);
malloc = 0;
calloc = 0;
realloc = 0;
free = 0;
malloctime = 0;
}