The VikiD Truth

Knowledge base / Computing / Lisp family

linuxtools

pmap

The truth about a running program’s memory is that it isn’t one big block – it’s a patchwork map of regions, each with its own purpose and permissions. pmap prints that map.

What it is, in plain words

pmap (from the procps-ng package, installed almost everywhere) reports the memory map of a process: every region of virtual address space it has, how big each is, what permissions it has (read, write, execute), and what backs it – a file like /usr/lib/libc.so.6, the heap, the stack, or anonymous memory.

It is really a friendly front end to the file /proc/<pid>/maps (and, with -X, /proc/<pid>/smaps), which the kernel maintains for every process.

Why it matters

“How much memory is this program using?” sounds simple and isn’t. A process maps shared libraries it shares with everyone, reserves address space it never touches, and allocates heap it may never give back. pmap lets you see which of those you are looking at, so you can tell a real leak from a scary-looking number. It also teaches you, very concretely, how a process is laid out in memory – essential for C, debugging and security work.

An everyday analogy: a city zoning map

A city’s area isn’t “used” uniformly. There are residential zones, industrial zones, parks, roads and plots that are zoned but empty. A zoning map tells you what each area is for and who’s allowed to do what there. pmap is the zoning map of a process: code zones (read + execute), data zones (read + write), shared library districts, and big reserved plots that are mostly empty.

flowchart TB
  K["kernel space (not visible)"]
  S["stack ↓ (rw-)"]
  M["mmap region: shared libs, anon maps"]
  H["heap ↑ (rw-)"]
  D[".data / .bss (rw-)"]
  T[".text code (r-x)"]
  K --- S --- M --- H --- D --- T

A hands-on example

Look at your own shell:

pmap $$

Output (trimmed):

12345:   bash
000055d0c1a00000    180K r---- bash
000055d0c1a2d000    756K r-x-- bash
000055d0c1aea000    228K r---- bash
000055d0c1b24000     16K rw--- bash
000055d0c2f1e000   1320K rw---   [ anon ]
00007f2a1b200000   1940K r-x-- libc.so.6
...
00007ffd4e9f1000    132K rw---   [ stack ]
 total            10248K

The extended view adds the numbers that actually matter:

pmap -x $$
Address           Kbytes     RSS   Dirty Mode  Mapping
...
total kB           10248    4120    1536

For the most detail, including PSS (proportional set size – shared pages divided fairly among their users), use:

pmap -X $$          # wide output from smaps
pmap -XX $$         # everything the kernel reports

Watching a leak

Write a little C program that leaks on purpose:

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void) {
    for (;;) {
        char *p = malloc(1 << 20);   /* 1 MiB */
        memset(p, 1, 1 << 20);       /* touch it so it becomes resident */
        sleep(1);
    }
}
gcc leak.c -o leak && ./leak &
watch -n1 "pmap -x $! | tail -1"

The RSS total climbs a megabyte a second. Large malloc calls use mmap, so you’ll also see new [ anon ] regions appear. Kill it with kill %1.

Common misconceptions

Connections

@ linux.die.net understanding-process-memory

Last edited · 3 revisions

Tags: #Computing