Home / Alt manpages / proc_pid_smaps(5)

  • proc_pid_smaps(5)
  • File format
  • linux

Read Linux Process Memory by Mapping with /proc/pid/smaps

You will finish with a repeatable way to inspect a process's memory mappings, identify which mappings are resident, and avoid treating virtual size as physical memory use. The examples use the local proc_pid_smaps(5) manpage from Linux man-pages 6.7, package version 6.7-2. Kernel output can contain extra fields on newer systems.

Allow about ten minutes. You need a shell and a process ID. Reading your own process normally needs no elevated privileges. Reading another user's process may be restricted by the kernel's ptrace access rules, so do not start with sudo and do not weaken those rules just to make a diagnostic command work.

1. Pick a process and confirm its mapping file

Use the shell's own process first. This keeps the test harmless and avoids guessing whether a long-running service can be inspected:

$ PID=$$
$ printf 'PID: %s\n' "$PID"
PID: 28417
$ test -r "/proc/$PID/smaps" && echo readable
readable

Your PID will differ. The file is a live view of the process, not a saved report. Mappings can appear or disappear while you read it, and the process may exit before the next command. The file exists only when the kernel has enabled CONFIG_PROC_PAGE_MONITOR.

Checkpoint: if the test fails, check the path and process state without changing anything:

$ ps -p "$PID" -o pid=,comm=,stat=
28417 bash S

If the process has gone, choose a new PID. If /proc/$PID/smaps is absent for every process, check the kernel configuration and container or host restrictions before changing permissions.

2. Read one mapping block

Each mapping begins with the same address, permissions, offset, device, inode and pathname style used by /proc/$PID/maps. Its following lines describe memory for that mapping. Show the first block with:

$ sed -n '1,24p' "/proc/$PID/smaps"
00400000-0040b000 r--p 00000000 08:01 123456 /usr/bin/example
Size:                 44 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                  12 kB
Pss:                  12 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:        12 kB
Private_Dirty:         0 kB
Referenced:           12 kB
Anonymous:             0 kB
Swap:                  0 kB
Locked:                0 kB
ProtectionKey:         0
VmFlags: rd mr mw me sd

Exact values, field order and pathname vary. Size is the virtual mapping size. Rss is the part currently resident in RAM. Pss is the proportional share: a shared page is divided between the processes using it. That makes PSS more useful than RSS when you are estimating a process's attributable memory, but it is still a snapshot and can change during the read.

The clean and dirty shared and private fields explain the RSS split. Anonymous counts memory not belonging to a file. Swap reports would-be-anonymous memory also in swap. Referenced reports pages currently marked as accessed; it is not a lifetime access counter.

3. Find the largest resident mappings

For a quick human inspection, print every mapping header and its next RSS line. This does not calculate a total, and it deliberately leaves the original address and pathname visible:

$ awk '
  /^[0-9a-f]+-[0-9a-f]+ / { mapping=$0 }
  /^Rss:/ { print $2, $3, mapping }
' "/proc/$PID/smaps" | sort -nr | head -10
460 kB 00400000-0048a000 r-xp 00000000 fd:03 960637 /bin/bash
208 kB 7f2c1a000000-7f2c1a021000 rw-p 00000000 00:00 0
...

The first column is the RSS value and the second is normally kB. The example is intentionally a display command, not a parser contract. New kernels can add fields, and pathnames can contain spaces. For automation, parse recognised field names and keep the mapping header as a separate record.

4. Compare RSS, PSS and total mapping size

Use a small aggregation when you need a rough process-wide view. The sum of per-mapping values is useful for investigation, but it is not an accounting guarantee: the process can change while the file is being read, and shared pages are represented differently by RSS and PSS.

$ awk '
  /^Size:/ { size += $2 }
  /^Rss:/  { rss  += $2 }
  /^Pss:/  { pss  += $2 }
  END {
    printf "Size: %d kB\nRSS:  %d kB\nPSS:  %d kB\n", size, rss, pss
  }
' "/proc/$PID/smaps"
Size: 18432 kB
RSS:  7216 kB
PSS:  4980 kB

Do not compare the first number with a physical-memory graph and call it a leak. A large virtual mapping may have little resident memory. Do not add PSS values from several processes and assume shared pages have disappeared from the system total: PSS is intended to apportion them, not to replace a whole-system memory measurement.

5. Check flags and page sizes

VmFlags is a compact set of two-letter flags for each virtual memory area. Common entries include rd readable, wr writable, ex executable, sh shared, mr may read, mw may write and me may execute. Other flags describe stacks, huge pages, soft-dirty state, userfaultfd tracking and more. Interpret a flag using the installed manpage rather than guessing from its letters.

KernelPageSize is the page size used by the kernel to back the area. MMUPageSize is the size used by the memory-management unit. They are usually equal, but the distinction matters on some architectures. ProtectionKey is present only on supported x86 builds with the relevant kernel option.

Keep parsers tolerant. A field can be unavailable on an older kernel, added on a newer kernel, or omitted for a mapping where it does not apply. Match complete field names such as Private_Dirty:, not a fixed line number.

6. Inspect another process safely

Once the self-test works, substitute a real PID:

$ TARGET_PID=1234
$ test -d "/proc/$TARGET_PID" && ps -p "$TARGET_PID" -o pid=,user=,comm=
 1234 alice    example
$ sed -n '1,12p' "/proc/$TARGET_PID/smaps"
00400000-0048a000 r-xp 00000000 fd:03 960637 /usr/bin/example
Size:                552 kB
KernelPageSize:       4 kB
MMUPageSize:          4 kB
Rss:                 460 kB

Use the target's identity and command output to avoid a PID-reuse mistake. If the read returns permission denied, treat that as an access boundary. Ask the process owner or administrator to run the diagnostic in the appropriate context. Avoid broad capability changes, disabling hardening, or exposing the file through a service.

The procps pmap command can display similar information in a form that may be easier to parse, but it is a separate program. The installed version here is procps-ng 4.0.4. Use smaps when you need the per-field detail described above.

Done means

  • You read /proc/$PID/smaps for a known, live process.
  • You can distinguish virtual Size, resident Rss and proportional Pss.
  • You understand that the file is a changing snapshot and that kernel versions can add fields.
  • You can inspect mapping flags without inferring their meaning from the abbreviations.
  • You treat permission failures as access controls rather than reasons to weaken the host.