There recently was a couple of questions asking why Ubuntu is seemingly using more memory than accounted for by processes/services - here and here.
However, I have the exact opposite situation. On my server, the memory used by all processes seems to be higher than the total memory used. Let me provide the evidence.
Output of free -m
:
total used free shared buff/cache available
Mem: 64277 15014 34424 31 14837 48530
Swap: 8191 0 8191
Output of arcstat
:
time read miss miss% dmis dm% pmis pm% mmis mm% size c avail
09:38:57 0 0 0 0 0 0 0 0 0 9.8G 9.8G 41G
Output of ps aux | awk '{sum +=$6}END{print sum}'
:
6351512
So what this means for me is:
free -m
reports a total of 15.0 GB memory used (shared memory is neglible). Subtract from this 9.8 GB reported by arcstat
for ZFS ARC Cache. The remaining result is around 5.2 GB of "real" used memory. But the sum of column 6 in ps aux
(RSS - resident set size) totals to 6.35 GB. This would mean that reported memory used by all processes is 1.15 GB higher than it actually is shown by free -m
.
I wonder if there is a way I can correctly calculate the memory used by all processes, so it matches the used memory (after ZFS cache and shared ramdisks are subtracted)?
So as many are probably aware, the memory statistics reported by
ps
(and the metric RSS itself) aren't entirely accurate because of shared memory pages.There is another tool called
smem
, which correctly reports the proportionate set size for each process - that is each process' memory consumption where the shared memory is divided in a sane way between processes.From
man smem
:However, there are a few handy tricks for installing and configuring
smem
to easily report actual used memory by all processes.Installing and configuring
smem
First, if you want to install
smem
, you need to have the Universe repository enabled. Make sure this line is uncommented in/etc/apt/sources.list
(for Ubuntu 22.04):When you're normally trying to install
smem
, it wants to install a ton of dependencies (a little over 100 packages), because it has a recommended dependency onpython3-matplotlib
for generating graphical charts.Since I don't need this (and anybody with a server probably don't need it either), it's possible to only install the base package with this command:
Notice the dash after
python3-matplotlib
- this indicates that this packages should not be installed. Another option is to use:This has the same result, which will only install the
smem
package.The final trick is to fix the columns, so you can correctly use
awk
, or export the metrics in a way where you can trust the columns. To do this, we need to move thecommand
column to the rightmost place, since thecommand
field can include additional spaces we can't control.To fix the column layout and size,
smem
should be run with these options:In addition, to include all processes, it has to be run as
sudo
. I've defined the following alias forsmem
:So in the following, when I type the command
smem
, it does in fact run the command with the above options.Comparing
smem
andps
metricsNow we can correctly compare the metrics of
ps aux
andsmem
. I was expecting a "real" used memory of 5.2 GB, butps aux
reported 6.35 GB used. Below are the results fromsmem
.Count of RSS from
smem
:Count of PSS from
smem
:Now it's clear that the RSS reported is roughly similar (a little higher from
smem
). But it's also clear that the proportionate set size (PSS) more correctly matches the expected memory usage among processes - 5.2 GB.So to correctly measure total process memory usage, the PSS metric from
smem
seems to give the most meaningful result.