Notes on what Linux's /proc/<pid>/smaps fields mean

January 13, 2012

Because I was just digging around in the kernel source to determine this (it's a long story), here is some notes about what the fields of the smaps file mean and how they're calculated. The factory for this particular sausage is fs/proc/task_mmu.c (at least as of the current git tree).

For each VMA mapping that gets listed in smaps, the kernel walks all of the PTEs associated with it and looks at all of the known pages. Each PTE is then counted up:

  • the full PTE size is counted as Rss.
  • if the page has been used recently, it's added to Referenced.
  • if the page is mapped in only one process it is labeled as private; its full size is added to Pss.
  • if the page is mapped in more than one process it is shared and the amount it adds to Pss is divided by the number of processes that have it mapped.

(If the PTE is for something in swap it only adds to the Swap size.)

Note that a 'private' page is not quite as private as you might think. Because processes map pages independently of each other, it's possible to have a shared page that is currently mapped only by a single process (eg only one process may have called an obscure libc function recently); such pages are counted in 'private'.

The Size of a mapping is how much address space it covers.

If the mapping has been locked into memory via mlock() or the like, Locked is the same as Pss (ie, it is this process's fair share of the amount of locked memory for this mapping); otherwise it is 0 kB.

Given that looking at smaps requires walking the pages of all of the VMAs, I suspect that it's a reasonably costly operation. It'd probably be a bad idea to build a tool that did it a lot, especially if the tool scanned all processes in the system.

(Smem uses smaps, but it doesn't normally run repeatedly in the way that, say, top does.)

Comments on this page:

From at 2012-01-13 09:09:36:

I tool I wrote using this interface:

(Note that the newer VmSwap-field is much faster.)

From at 2012-06-04 11:05:36:

I understand what RSS and PSS are. Does "Size" account for swap? What does it include that is not also counted in the other fields (I have seen an entry where size is 2044 kB, KernelPageSize and MMUPageSize are both 4 kB and everything else is 0)? If I wish to monitor the total memory usage of a process (including swap) does it make more sense to consider PSS and Swap, rather than Size?

By cks at 2012-06-04 11:49:44:

Size is the total virtual address space that the mapping covers. This means that all other numbers are a subset of Size (at most they're equal to it). So Size covers swapped pages, shared pages, and private pages (and all resident pages), but it also covers pages that have never been mapped into the process or that have been de-mapped since then (without going to swap).

Monitoring Size is relatively useless by itself, at least in my view; in my experience plenty of programs map address space that they never touch, so Size can be very misleading about real RAM usage. RSS or PSS plus Swap seems a better approximation if you want to monitor that sort of memory usage.

(Now, a disclaimer: I haven't looked into how shared swap pages are accounted for, assuming that they're even possible. They may show up as Swap in each process that has a PTE for them.)

From at 2012-06-04 14:05:23:

Wow, thanks for such a quick response.

I want to monitor the memory usage (swap included) for a single process, top-style. You mention that it is a costly operation; do you know of a better option than smaps? Is there a way to get those values already summed, rather than parsing and summing all the entries in smaps?

Thanks again!

By cks at 2012-06-04 15:36:27:

If you want everything summed and you don't care about PSS, I think that looking at /proc/<pid>/status is probably your best bet. I don't know if there's an existing program that shows the swapped figure in addition to RSS; my impression is that most programs ignore swapped memory. If you do need PSS, as far as I know smaps is the only source. You probably want to start with smem and modify it to report on only a single PID and do so repeatedly (it's written in Python, so this shouldn't be too hard).

(I don't know how efficient /proc/<pid>/status is, but I believe that top uses it and you probably can't really do better.)

Written on 13 January 2012.
« A Yum plugin I would like: using a local DVD as a repo source
What do we mean when we talk about something's memory usage? »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Jan 13 01:36:35 2012
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.