Why Does ‘free -m’ Show Much More Used Memory Than ‘ps aux’ RSS?
The article explains why Linux’s free command reports far higher used memory than the RSS values shown by ps aux, by breaking down buffers, cache, slab allocations, page tables and shared libraries, and provides shell scripts to calculate each component.
Memory reporting basics
On Linux the free -m command reports total, used, free, buffers and cached memory. The used column includes reclaimable buffers/cache, so the real pressure on RAM is used - buffers - cache. For example, a system with Mem: 48262 total 7913 used 40349 free 14 buffers 267 cache actually has only about 7913‑(14+267)=7632 MiB of non‑reclaimable usage.
Dropping caches
# sudo sysctl vm.drop_caches=3
# free -mAfter clearing page cache, the used column drops (e.g., from 7913 MiB to 7676 MiB), confirming that most of the original usage was cache.
Per‑process resident memory (RSS)
The RES column shown by top or nmon corresponds to the resident set size (RSS) taken from the second field of /proc/[pid]/statm. The file reports memory usage in pages; the second field is the number of resident pages.
Summing RSS across all processes
# RSS.sh
#!/bin/bash
RSS=0
for PROC in $(ls /proc | grep "^[0-9]"); do
if [ -f /proc/$PROC/statm ]; then
TEP=$(awk '{print $2}' /proc/$PROC/statm)
RSS=$((RSS + TEP))
fi
done
RSS=$((RSS * 4)) # assuming 4 KB pages
echo "${RSS}KB"This script reports the total resident memory of all processes (e.g., ~7024 MiB). The value is lower than the
free usedcolumn because it does not include kernel allocations, page‑table structures, or reclaimable cache.
Kernel slab allocations
Kernel slab caches keep frequently used kernel objects and can consume hundreds of megabytes. The total slab memory can be obtained from /proc/slabinfo:
# echo $(awk 'BEGIN{sum=0}{sum+= $3*$4} END{print sum/1024/1024}' /proc/slabinfo) MBTypical output is around 904 MiB.
Page‑table overhead
Page‑table structures are accounted for in /proc/meminfo under the PageTables entry. The size is reported in kilobytes:
# echo $(grep PageTables /proc/meminfo | awk '{print $2}') KBOn a 48 GiB system this may be about 58 052 KB (~57 MiB).
Combining the components
# cm.sh – combine RSS, slab and page‑table numbers
#!/bin/bash
RSS=0
for PROC in $(ls /proc | grep "^[0-9]"); do
if [ -f /proc/$PROC/statm ]; then
TEP=$(awk '{print $2}' /proc/$PROC/statm)
RSS=$((RSS + TEP))
fi
done
RSS=$((RSS * 4)) # KB
PageTable=$(grep PageTables /proc/meminfo | awk '{print $2}')
SlabInfo=$(awk 'BEGIN{sum=0}{sum+= $3*$4} END{print sum/1024/1024}' /proc/slabinfo)
printf "rss+pagetable+slabinfo=%sMB
" $(echo "${RSS}/1024 + ${PageTable}/1024 + ${SlabInfo}" | bc)
free -mThe script prints the three components (e.g., rss=7003756KB, pagetable=59272KB, slab=904.3MB) and their sum (~ 7800 MiB), which is close to the
free usedvalue (≈ 7629 MiB). The remaining difference (~171 MiB) is caused by double‑counting shared libraries: each process’s RSS includes the full size of shared objects, so the same physical pages are counted multiple times.
Key take‑aways
Memory reported by free consists of process resident pages, kernel slab caches, and page‑table structures.
Buffers and cache are reclaimable; dropping them with vm.drop_caches reduces the apparent used memory.
Per‑process RSS overestimates physical usage because shared libraries are counted for every process that maps them.
Accurate accounting would require subtracting the shared‑library overlap, which is non‑trivial.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
