Following on from this question. Debian, if that matters.
I understand that some memory is shared between forked processes. How then can I determine how much memory is used by a process/set of forked processes?
Using the smem tool recommended in this similar question, I get values like:
Command Swap USS PSS RSS
/usr/sbin/spamd --create-pr 0 16820 24974 41628
spamd chil 0 19388 27581 44176
spamd chil 0 32328 40038 55708
I understand the swap column, and the RSS column is what is normally reported (e.g. in ps). From reading the smem documentation, it sounds like USS is the memory specifically for that child, and PSS is a portion of the memory shared across the processes. However, adding USS to PSS gives higher values than RSS, and I thought that the sharing would mean less (so I'm presumably interpreting incorrectly).
I'm not tied to the smem tool. I would just like some way of getting a "memory use" number that somewhat accurately reflects the amount of real memory that the process is using.
Proportional set size is probably the best figure of memory use per-process you have available. It's the unique set size + (the shared pages / # of processes sharing).
So one process has used 44176 pages, of which 19388 are unique to that process. This means that 24788 are shared with others.
Looking at PSS as USS + (shared weight). The weight in this case is 8193, which is the proportion of shared memory pages (24788) attributable to this process. The more instances of an application you have sharing pages, the lower the weight for each process.
You can sum PSS across multiple processes and you won't count shared pages more than once. You can't, however, sum USS and PSS and expect RSS because PSS already includes USS.
As I understand it (but someone please do correct me if I'm wrong), only the program segment is shared when a process forks - the data segments become separate.
So, the executable (binary) and any shared libraries loaded will be shared between the processes.
Each process will get its own copy(*) of any memory that was allocated before the fork, but any memory allocated subsequently will be unique to that process.
(*) a really clever O/S could avoid having to actually allocate data segments for the child's copy by using a copy on write algorithm, such that the memory only gets allocated if either process tries to change it. See here.