59

For a given process in /proc/<pid>/smaps, for a given mapping entry what are:

  1. Shared_Clean
  2. Shared_Dirty
  3. Private_Clean
  4. Private_Dirty

Is Shared_Clean + Shared_Dirty the amount of memory that is shared with other processes? So it is like shared RSS?

Similarly is Private_Clean + Private_Dirty the amount of memory that is available for only one process? So it is like private RSS?

Is the PSS value = PrivateRSS + (SharedRSS / number of processes sharing it)?

Some more questions after reading this link: LWN

Now lets talk about the process as a whole, whose smaps entry we are looking at.

I noticed that if I do Shared_Clean + Shared_Dirty + Private_Clean + Private_Dirty for every smaps entry for the process I get the RSS of the process as reported by ps, which is pretty cool. For e.g.

ps -p $$ -o pid,rss

Will give me the (approx) same value for rss as the sum of every Shared_Clean , Shared_Dirty , Private_Clean , Private_Dirty entry in /proc/$$/smaps.

But what about PSS for the entire process? So, from the example above how do I get the PSS for $$ ? Can I just add the PSS entry for every smaps mapping and arrive at PSS for $$ ?

And what about USS for the entire process? Again taking the example above I am guessing that I can arrive at the USS for $$ by summing up only the Private_* entries for every smaps entry for $$..right?

Notes:
PSS= Proportional set size.
USS= Unique set size.

2 Answers2

61

Clean pages are pages that have not been modified since they were mapped (typically, text sections from shared libraries are only read from disk (when necessary), never modified, so they'll be in shared, clean pages).
Dirty pages are pages that are not clean (i.e. have been modified).

Private pages are available only to that process, shared pages are mapped by other processes*.

RSS is the total number of pages, shared or not, currently mapped into the process. So Shared_Clean + Shared_Dirty would be the shared part of the RSS (i.e. the part of RSS that is also mapped into other processes), and Private_Clean + Private_Dirty the private part of RSS (i.e. only mapped in this process).

PSS (proportional share size) is as you describe. Private pages are summed up as is, and each shared mapping's size is divided by the number of processes that share it.
So if a process had 100k private pages, 500k pages shared with one other process, and 500k shared with four other processes, the PSS would be:

100k + (500k / 2) + (500k / 5) = 450k

Further readings:

Regarding process-wide sums:

  • RSS can be (approximately+) obtained by summing the Rss: entries in smaps (you don't need to add up the shared/private shared/dirty entries).

    awk '/Rss:/{ sum += $2 } END { print sum }' /proc/$$/smaps
    
  • You can sum up Pss: values the same way, to get process-global PSS.
  • USS isn't reported in smaps, but indeed, it is the sum of private mappings, so you can obtain it the same way too

*Note that a "share-able" page is counted as a private mapping until it is actually shared. i.e. if there is only one process currently using libfoo, that library's text section will appear in the process's private mappings. It will be accounted in the shared mappings (and removed from the private ones) only if/when another process starts using that library.
+The values don't add up exactly for all processes. Not exactly sure why... sorry.

Mat
  • 52,586
  • Thanks for the great answer. Appreciate it. I read the LWM article and that inspired me ask few more questions, so I added them to my question above. – Ankur Agarwal Mar 04 '12 at 21:01
  • Great! it is very very helpful!! – camino Mar 30 '12 at 06:01
  • I'm still confused about shared_dirty - is the dirty nature of this preventing it from being shared still? – Kevin Jun 17 '13 at 23:40
  • @Kevin: if they weren't shared, they wouldn't be accounted in Shared_Dirty - could you clarify your question? – Mat Jun 18 '13 at 04:26
  • dirty means modified from the orig. process, right? which isn't that how it goes from being shared to being local? – Kevin Jun 19 '13 at 04:43
  • Dirty means modified. If it's shared memory, it might not be from the "original process". Modifications to e.g. MAP_SHARED mmaps are visible to all processes sharing the same region. Modifications to a MAP_PRIVATE mapping should be accounted as private though. (I'd need to set up a test to illustrate/check this, don't have the time right now.) – Mat Jun 19 '13 at 05:42
  • @Mat, Why the total smaps Pss memory size is different procarnk Pss size for the same PID? For example I got 121882K thru procrank and 215655kB with smaps. – lourem koba May 09 '17 at 10:47
  • Having a set of js processes started up via node, if I want to know how much RAM would be freed if they were to be stopped, am I correct in interpreting the smaps metrics in the following manner: max potential freed RAM would be the sum of PSS values and the min freed RAM would be the sum of private pages (dirty+clean)? – one-liner Jan 24 '19 at 10:23
3

In recent kernels, /proc/$PID/smaps_rollup contains the information summed up over all mapping in the whole process (reference: https://docs.kernel.org/filesystems/proc.html). For example:

Rss:              640096 kB
Pss:              463041 kB
Pss_Dirty:        400291 kB
Pss_Anon:         378836 kB
Pss_File:          62264 kB
Pss_Shmem:         21941 kB
Shared_Clean:     195048 kB
Shared_Dirty:       9560 kB
Private_Clean:     38748 kB
Private_Dirty:    396740 kB
Referenced:       640024 kB
Anonymous:        378836 kB
...
fwyzard
  • 211