PMMM - The Poor Man's Memory Monitor
 was written by Burton M. Strauss III (BStrauss@acm.org)

PMMM is based in large part on a concept and code from Luca Deri's leaks.c, part of NTop.

Go to the SourceForge Project Page

So, how did we get from an shim in Ntop to PMMM?

I like problem solving. Even if it isn't really a problem. It was something fun and interesting to play with. You get the picture...

OK, but why ANOTHER "malloc replacement"?

Existing drop-in malloc replacements seemed to be too co$tly or too complex for my simple needs. Besides, they focus on the wrong thing (for my needs). Either they make millions of mallocs terribly efficient, or they are huge, slow, complex things to allow a developer to find every single memory leak. I wanted something simple enough to leave in a long-running production program that would add enough value to overcome it's costs (maybe not in version 12.0, but certainly in versions 0.1, 0.2 and even 1.0).

Something simple. Something that would make it obvious if there was a leak in a long running program. Something that might trade some human oversight for automation - I figured that I could run my eye over a list of allocations after the program has run for six or 12 hours and - if I knew where the memory had been allocated - check for leaks based on constant growth of memory requirements and unfreed allocations. Something that produced statistics and reports - I love them! Something like this:

Block
#
Size
(bytes)

Address
Setting
type@program(line)

When
0. 3480 0x804ebf8 m@initialize.c(91) Fri Jan 25 11:09:15 2002
1. 3480 0x804f998 m@initialize.c(93) Fri Jan 25 11:09:15 2002

And it produced statistics about memory allocations, which does give visibility to the systems administrator about Ntop's memory usage without much impact on execution:

(Reported by malloc):Total:1361044
Used:134558898.9%
Free:154561.1%in 16 chunks
mmap:2 chunks,532480 bytes
Tracking table:354 slots used out of 1000.
Tracing allocations of at least 17 bytes
table full reported flag is 0
Allocation sizemalloc calloc reallocfree   Alloc.
Bytes
Freed
Bytes
InUse
Bytes
Failed
<= 16 bytes50943 4189 41890
<= 256 bytes2404091393804325295127480
<= 1024 bytes12020554704017520295200
<= 4096 bytes75630037947203794720
<= 16384 bytes2002222842228400
<= 65536 bytes1000222840222840
larger220210485605242725242880
frees (size not tracked)   656    
Totals:9491111285415618725893719725010

Hog heaven - it produced statistics!

Before sending a huge, unsolicited patch to Luca Deri (the great ghu of Ntop), I asked him about it, and he suggested it could be applied more generally. Hence PMMM.

The Starting Point

Ntop

Luca Deri's Ntop had a malloc shim in it's leaks.c module. When I started working with Ntop, there were actually two versions. One was a basic shim that didn't do much, but at least it worked (it warned the developer of a zero or large allocation, and it cleared out the buffer so unallocated space would be obvious):

void* ntop_safemalloc(unsigned int sz, char* file, int line) {
  void *thePtr;

#ifdef DEBUG
  if((sz == 0) || (sz > 32768)) {
    traceEvent(TRACE_WARNING, "WARNING: called malloc(%u) @ %s:%d",
               sz, file, line);
  }
#endif

  thePtr = malloc(sz);
  memset(thePtr, 0xee, sz); /* Fill it with garbage */
  return(thePtr);
}

The second version - which I couldn't get to compile - malloced a little buffer for each allocation and looked like it would make a linked list of them.

Both used a #define "shim" to insert themselves into the malloc call, rather than relying on the GCC-only hook. Of course, they were then limited to tracking allocations in the Ntop source, not from other sources. But it was neat and fairly clean.

I liked the neatness of the shim. And I love statistics about long-running programs, even if there really isn't much I can do about it.

So I started to modify the version in leaks.c that worked to be a little bit better about tracking stuff without the overhead of the malloc'ed linked list. Instead I used two static tables (allocations and statistics) and some parameters to decide what to track, vs. ignore.

It could track 100%, or by setting the parameters, only track big allocations.

For post-mortem usage, the allocation table can be dumped at the end of the run (size, pointer, from where and when allocated). This allows us to see some memory leak patterns, for example 100s of allocations from a specific place in the code.

Lastly, having our own routines could allow us to do special case tuning (such as a program managed queue of packet sized entries) if it later became desirable. See, like many programs, Ntop has unique memory access patterns, and those could - conceiveably - be taken advantage of to reduce calls to malloc, overhead, etc.

I could have left it there, incorporated it into Ntop and been a happy camper. But I've rarely been able to leave well enough alone. And besides, I needed SOMETHING to keep my mind busy on sabatical. So, the goal of the PMMM was just a little bit more...