Inspect a Linux Process Memory Map with pmap
You will use pmap to see which address ranges a Linux process has mapped, then use its extended output to compare mapped size with resident memory. You will also filter a range, show real file paths, and handle a PID that has disappeared. Allow about ten minutes. You need the procps package and a shell; the examples only read process information and normally need no elevated privileges.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide was checked with procps version 2:4.0.4-4ubuntu3.3. Output varies with the process, kernel and installed libraries, so use the shape of the output as the check rather than copying its addresses.
1. Choose a live process
For a quick inspection, use the shell's own PID. The shell expands $$ before starting pmap, so the command does not depend on guessing a process number:
$ pmap $$
000055... 192K r---- bash
000055... 956K r-x-- bash
00007f... 2988K r---- locale-archive
...
total 7752K
The first column is a virtual address. The size column is the mapped size in KiB, followed by permissions and a mapping name. The final total is the total mapped address space reported by this invocation. A process can have anonymous mappings, shared libraries, a stack, and special kernel-provided mappings, so a long list is normal.
To inspect another process, replace PID with a real number. Find one without changing anything:
$ pgrep -a -f 'YOUR-PROCESS-NAME'
1234 /usr/bin/YOUR-PROCESS-NAME --example
$ pmap 1234
Use a process you are allowed to inspect. Access to another user's /proc/PID data can be restricted by the kernel's permissions and security settings. Running the command as root may reveal more, but it does not make the map a measurement of physical RAM.
2. Add resident and dirty memory columns
The default listing is useful for layout, but it does not show how much of each mapping is resident. Add -x, or its long form --extended:
$ pmap -x $$
Address Kbytes RSS Dirty Mode Mapping
000055... 192 180 0 r---- bash
000055... 956 828 0 r-x-- bash
...
total 7752 4936 412
Kbytes is the mapped size, RSS is the resident set size, and Dirty is the dirty amount shown for that mapping. These columns answer different questions. A large mapped library or reserved region is not necessarily occupying the same amount of physical memory at that moment. The totals are a snapshot, not a promise that the process will keep those values.
Checkpoint: rerun the command if you are comparing values over time. Do not treat a single pmap -x result as a leak diagnosis. Allocators, lazy loading and concurrent activity can all change the map between two readings.
3. Show paths and device details when names are ambiguous
Normal output may identify a mapping only by its basename. Use -p to show the full path for file-backed mappings:
$ pmap -p $$ | sed -n '1,6p'
1234: /bin/bash -c ...
000055... 192K r---- /usr/bin/bash
000055... 956K r-x-- /usr/bin/bash
If you need the mapped file's device and offset, use -d instead. Its columns include Offset and Device, which can distinguish mappings that share a displayed name. These are reporting choices; they do not alter the process or its mappings.
4. Narrow the report to an address range
Pass -A followed by one argument containing the low and high addresses separated by a comma. The comma is part of the argument:
$ pmap -A 0,ffffffff $$
total 0K
The example is intentionally narrow on a normal 64-bit process, so it commonly reports no matching mappings. To choose a useful range, first run pmap $$ and copy an address range from its output, then pass a suitable lower and upper bound. Do not insert a space after the comma. A range with no matches is a successful report, not evidence that the process has no memory.
5. Make scripts quieter and handle missing PIDs
Use -q when the header and footer are noise for a human-readable pipeline. It keeps the mapping rows while omitting some surrounding lines:
$ pmap -q $$ | sed -n '1,3p'
000055... 192K r---- bash
000055... 956K r-x-- bash
000055... 212K r---- bash
A process can exit between discovering its PID and reading its map. The manual documents exit status 42 when not all requested processes are found, and 1 for a general failure. Capture the status before another command overwrites it:
pmap "$PID" >/tmp/pmap.out 2>/tmp/pmap.err
status=$?
case "$status" in
0) sed -n '1,12p' /tmp/pmap.out ;;
42) printf '%s\n' 'The process was missing or ended during the check.' >&2; exit 42 ;;
*) cat /tmp/pmap.err >&2; exit "$status" ;;
esac
Replace $PID with a value supplied by your own script. Do not use an untrusted string as a shell command. The temporary files above contain process mapping information; remove them after review if that information should not remain on disk:
$ rm -f /tmp/pmap.out /tmp/pmap.err
That cleanup is optional and irreversible for those reports. Do not run it until you have finished checking them.
6. Leave configuration alone unless you need it
This version also supports procps configuration options: -c reads the default configuration, -C FILE reads a specified file, -n creates a new default configuration, and -N FILE creates one at a specified path. The creation options do not accept PID arguments. They are separate from inspecting a process and can create or overwrite configuration state, so keep them out of an ordinary diagnostic command unless you have a clear configuration task and a backup or new destination.
For more detail, run man pmap. The installed manual is the authority for this machine, especially for the extra detail modes -X and -XX, whose output follows kernel-provided data and can change between systems.
Done means
- You identified a live PID and produced a normal
pmaplisting. - You used
-xwhen you needed mapped, resident and dirty columns. - You used
-por-dwhen a basename was not enough to identify a mapping. - You kept the low and high values for
-Ain one comma-separated argument. - Your script distinguishes exit status
42from a general failure. - You did not change process state or use elevated privileges without a specific access reason.