Demo: Ten Processes, Four Ways¶
Ten copies of a "Hello, World!" that sleeps, started four ways: from one static executable, from one dynamic executable, from ten different static executables, from ten different dynamic ones.
smem reports USS, PSS and RSS for each.
Goal¶
See what is shared between processes and what is not, and read the three metrics as answers to three different questions.
Background¶
generate.sh writes ten C files that differ only in the string they print; build.sh builds each one twice, dynamically (hello-NN, 16 KB) and statically (hello-static-NN, 800 KB).
The four instantiate-*.sh scripts start ten processes in the background, one per scenario, and kill.sh ends them.
Everything lands in work/, which clean.sh removes.
smem -P filters by command line; the -t row at the bottom is the total.
Build and run¶
./generate.sh
./build.sh
./instantiate-one-static-multiple-times.sh
smem -P '^\./work/hel' -c "pid command uss pss rss"
./kill.sh
Then the same with the other three instantiate-*.sh scripts, and ./clean.sh at the end.
Results and explanations¶
Ten processes from one static executable¶
PID Command USS PSS RSS
1416067 ./work/hello-static-01 52 115 708
1416074 ./work/hello-static-01 52 115 708
...
10 556 1186 7116
Each process has 708 KB resident and owns 52 KB of it: its stack, its data, the page the allocator touched.
The other 650 KB are the executable's code and read-only data, one copy in the page cache, mapped by all ten; PSS gives each a tenth of it.
Ten processes, 7.1 MB of RSS, 1.2 MB of actual memory.
Ten processes from one dynamic executable¶
PID Command USS PSS RSS
1416097 ./work/hello-01 100 104 1688
1416098 ./work/hello-01 100 104 1688
...
10 1044 1084 16872
RSS more than doubled, to 1,688 KB each, because libc is now a separate mapping and its resident pages count towards every process.
PSS barely moved: 104 KB, of which 100 KB is private.
libc is shared not just with these ten but with every process on the machine, hundreds of them, so each one's share of it rounds to almost nothing.
The sum of RSS is 16.9 MB; the memory in use is 1.1 MB.
Ten processes from ten different static executables¶
PID Command USS PSS RSS
1416114 ./work/hello-static-03 708 708 712
1416115 ./work/hello-static-04 708 708 712
...
10 7088 7088 7128
Now USS, PSS and RSS agree: ten different files, ten copies of libc's code linked into them, nothing in common, nothing shared.
7.1 MB of RSS, and 7.1 MB in use: six times what the same ten processes cost from one executable.
Ten processes from ten different dynamic executables¶
PID Command USS PSS RSS
1416142 ./work/hello-07 112 116 1688
1416137 ./work/hello-02 116 120 1692
...
10 1176 1216 16936
Ten different executables, but each is 16 KB and nearly all of a process is libc, which is still one copy.
USS is 12 KB higher than with one executable, for the one page of code each file has of its own; everything else is as before.
The four, side by side¶
| ten processes from | USS each |
PSS each |
RSS each |
real total |
|---|---|---|---|---|
| one static executable | 52 KB | 115 KB | 708 KB | 1.2 MB |
| one dynamic executable | 100 KB | 104 KB | 1,688 KB | 1.1 MB |
| ten static executables | 708 KB | 708 KB | 712 KB | 7.1 MB |
| ten dynamic executables | 116 KB | 120 KB | 1,692 KB | 1.2 MB |
Three things to take from it:
- Sharing is implicit and it is everywhere. Nobody asked for it; the kernel maps the same frames of the page cache into every process that runs the same file, and it does so for the executable and for every library.
RSSanswers "what does this process have mapped", not "what does it cost".PSSanswers the second, and sums to the truth;USSanswers "what would go away if this process did".- Dynamic linking is a memory decision, not only a disk one. Lab 01 built both kinds of executable; this is the difference at run time, times the number of processes.
Going further¶
smem -m -P hellolists the mappings instead of the processes: the executable, libc,ld-linux, each with its totalPSSacross the ten.- Make the ten dynamic processes write to a large global array and watch
USSgrow andPSSfollow: written pages are private, whatever they came from. - Start a hundred instead of ten (
num_timesin the scripts) and the per-processPSSof the static run drops to about 60 KB.
References¶
man 8 smem,man 5 proc(/proc/[pid]/smaps)