Prasanth Madhavan Prasanth Madhavan - 6 months ago 10
Linux Question

How to find how much memory is shared between forked process with copy-on-write in Linux?

If there is a process that reads a big file and saves it in its memory(or just a malloced char*), and that main process is forked, if the child process only reads from that memory(or the char*), according to copy-on-write, the memory where the pointer is saved is not copied, and both parent and child share the same memory until either one of them tries to write on that memory in which case the process makes a copy of the memory and changes that.

So my question is if there is a copy-on write implemented, is there a way to know the amount of memory that the child uses that is not shared with the main process?
In other words how much memory does a child process actually use, if it uses parents memory from some read calls?

top, or ps commands will only give the total amount of memory that the child is supposed to have. (i.e assuming that data in memory or pointer is copied by the child.)

Is there a way to get the amount of data that is actually used by CoW semantics?

I went through

/proc/[pid]/smaps
as suggested by aix and Mat, but all i found was lots of empty smaps files. I tried this command to find which files has data in them:
tail -n 5 */smaps | less

And the o/p that i got was

==> 1012/smaps <==

==> 1074/smaps <==

==> 10/smaps <==

==> 1148/smaps <==

==> 11862/smaps <==

==> 11/smaps <==

==> 1355/smaps <==

==> 1356/smaps <==

==> 1357/smaps <==

==> 1358/smaps <==

==> 1361/smaps <==

==> 13/smaps <==

==> 14900/smaps <==

==> 14/smaps <==

==> 1501/smaps <==

==> 15/smaps <==

==> 1684/smaps <==

==> 1685/smaps <==

==> 16/smaps <==

==> 17772/smaps <==

==> 17827/smaps <==

==> 17/smaps <==

==> 18490/smaps <==

==> 18/smaps <==

==> 1932/smaps <==

==> 1934/smaps <==

==> 19863/smaps <==

==> 19/smaps <==

==> 1/smaps <==

==> 20125/smaps <==

==> 20126/smaps <==

==> 20127/smaps <==

==> 20128/smaps <==

==> 20129/smaps <==

==> 20134/smaps <==

==> 20135/smaps <==

==> 20811/smaps <==

==> 20868/smaps <==

==> 20/smaps <==

==> 21116/smaps <==

==> 21774/smaps <==

==> 21/smaps <==

==> 22393/smaps <==

==> 22394/smaps <==

==> 22395/smaps <==

==> 22398/smaps <==

==> 22639/smaps <==

==> 22824/smaps <==

==> 22/smaps <==

==> 23009/smaps <==

==> 23058/smaps <==

==> 23059/smaps <==
Private_Dirty: 0 kB
Referenced: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB

==> 23835/smaps <==

==> 23961/smaps <==

==> 23962/smaps <==

==> 23963/smaps <==

==> 23964/smaps <==

==> 23/smaps <==

==> 24180/smaps <==

==> 24268/smaps <==

==> 24467/smaps <==

==> 24/smaps <==

==> 252/smaps <==

==> 25352/smaps <==

==> 25435/smaps <==

==> 25/smaps <==

==> 26465/smaps <==

==> 26/smaps <==

==> 27884/smaps <==

==> 27/smaps <==

==> 28/smaps <==

==> 29/smaps <==

==> 2/smaps <==

==> 303/smaps <==

==> 30/smaps <==

==> 316/smaps <==

==> 31/smaps <==

==> 32074/smaps <==

==> 32076/smaps <==

==> 32112/smaps <==
Private_Dirty: 0 kB
Referenced: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB

==> 32116/smaps <==
Private_Dirty: 0 kB
Referenced: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB

==> 322/smaps <==

==> 32466/smaps <==

==> 32467/smaps <==

==> 32/smaps <==

==> 33/smaps <==

==> 34/smaps <==

==> 37/smaps <==

==> 38/smaps <==

==> 3991/smaps <==

==> 3992/smaps <==

==> 39/smaps <==

==> 3/smaps <==

==> 4005/smaps <==

==> 4006/smaps <==

==> 4007/smaps <==

==> 4008/smaps <==

==> 4009/smaps <==

==> 4010/smaps <==

==> 4018/smaps <==

==> 4029/smaps <==

==> 4038/smaps <==

==> 4044/smaps <==

==> 4045/smaps <==

==> 4046/smaps <==

==> 4053/smaps <==

==> 4054/smaps <==

==> 4055/smaps <==

==> 40/smaps <==

==> 41/smaps <==

==> 42/smaps <==

==> 4339/smaps <==

==> 435/smaps <==

==> 436/smaps <==

==> 43/smaps <==

==> 44/smaps <==

==> 45/smaps <==

==> 46/smaps <==

==> 47/smaps <==

==> 48/smaps <==

==> 49/smaps <==

==> 4/smaps <==

==> 50/smaps <==

==> 51/smaps <==

==> 52/smaps <==

==> 53/smaps <==

==> 54/smaps <==

==> 55/smaps <==

==> 56/smaps <==

==> 57/smaps <==

==> 58/smaps <==

==> 5988/smaps <==

==> 59/smaps <==

==> 5/smaps <==

==> 6058/smaps <==

==> 6059/smaps <==
Private_Dirty: 0 kB
Referenced: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB

==> 60/smaps <==

==> 61/smaps <==

==> 62/smaps <==

==> 63/smaps <==

==> 64/smaps <==

==> 65/smaps <==

==> 66/smaps <==

==> 67/smaps <==

==> 68/smaps <==

==> 69/smaps <==

==> 6/smaps <==

==> 70/smaps <==

==> 71/smaps <==

==> 72/smaps <==

==> 73/smaps <==

==> 74/smaps <==

==> 771/smaps <==

==> 77/smaps <==

==> 782/smaps <==

==> 78/smaps <==

==> 79/smaps <==

==> 7/smaps <==

==> 80/smaps <==

==> 814/smaps <==

==> 819/smaps <==

==> 81/smaps <==

==> 82/smaps <==

==> 83/smaps <==

==> 84/smaps <==

==> 8654/smaps <==

==> 8655/smaps <==

==> 8656/smaps <==

==> 892/smaps <==

==> 8/smaps <==

==> 949/smaps <==

==> 950/smaps <==

==> 9/smaps <==

==> self/smaps <==
Private_Dirty: 0 kB
Referenced: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB


So what am i supposed to do now? I have processes that have blank smaps that are running. How do i get the smaps of those pid's?

NPE NPE
Answer

I don't know of a tool that would give you this information, but you can probably compute this based on /proc/[pid]/smaps:

   /proc/[pid]/smaps (since Linux 2.6.14)
          This file shows memory consumption for each of  the  process’s  mappings.
          For each of mappings there is a series of lines such as the following:

              08048000-080bc000 r-xp 00000000 03:02 13130      /bin/bash
              Size:               464 kB
              Rss:                424 kB
              Shared_Clean:       424 kB
              Shared_Dirty:         0 kB
              Private_Clean:        0 kB
              Private_Dirty:        0 kB

          The  first  of these lines shows the same information as is displayed for
          the mapping in /proc/[pid]/maps.  The remaining lines show  the  size  of
          the mapping, the amount of the mapping that is currently resident in RAM,
          the number of clean and dirty shared pages in the mapping, and the number
          of clean and dirty private pages in the mapping.

For details, see Getting information about a process' memory usage from /proc/pid/smaps.

Comments