Prasanth Madhavan - 7 months ago 20

Linux Question

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`

`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?

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`

.