Linux7 min read

Linux memory management: free, vmstat, and /proc

linuxmemorymonitoringtroubleshootingperformance

When someone says “my server is out of memory,” the first question is: are you sure? Linux memory reporting is confusing because Linux actually uses almost all available RAM — for caches. That’s normal and good. Understanding the difference between “used” and “available” is the key to reading memory stats correctly.

Reading free correctly

free -h

Output:

              total        used        free      shared  buff/cache   available
Mem:           15Gi       8.2Gi       1.1Gi       256Mi       6.1Gi       6.5Gi
Swap:         2.0Gi       0.0Gi       2.0Gi

The columns that matter:

  • total — total installed RAM
  • used — memory actively used by processes
  • free — completely unused memory
  • buff/cache — memory used for buffers and page cache
  • available — memory available for new applications (free + reclaimable cache)

The free column looks scary (1.1Gi out of 15Gi), but that’s fine. Linux caches aggressively. The available column (6.5Gi) is what actually matters.

The old “free + buff/cache = available” mental model helps. The kernel can drop caches instantly when an application needs memory.

The page cache

When Linux reads a file, it caches the contents in RAM. Subsequent reads are served from cache (fast) instead of disk (slow). This is why buff/cache is usually large.

Check cache effectiveness:

vmstat -s | grep cache

If the system has been running for a while and cache is large, that’s healthy. The system is reusing memory efficiently.

vmstat: real-time memory and CPU

vmstat 1 5

Output:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0  24576 452864 234560 6144000   0    0    12    45  234  567 12  3 84  1  0

Memory columns (in KB):

  • swpd — swap used
  • free — idle memory
  • buff — buffer cache
  • cache — page cache

Swap columns:

  • si — swap in (pages read from swap)
  • so — swap out (pages written to swap)

If si and so are consistently non-zero, you’re swapping.

CPU columns:

  • us — user time
  • sy — system time
  • id — idle
  • wa — I/O wait
  • st — stolen (VM only, time given to hypervisor)

High wa means the system is waiting on disk I/O. High st means the VM host is overcommitted.

/proc/meminfo

The raw data behind free:

cat /proc/meminfo

Key fields:

  • MemTotal — total usable RAM
  • MemFree — completely unused
  • MemAvailable — estimated available (what free shows as “available”)
  • Buffers — raw block device cache
  • Cached — page cache
  • SwapTotal — total swap
  • SwapFree — free swap
  • Dirty — memory waiting to be written to disk
  • Slab — kernel data structures cache

per-process memory

Memory usage per process:

ps aux --sort=-%mem | head -10

More detailed:

cat /proc/PID/status | grep -i mem
  • VmRSS — physical memory used
  • VmSize — virtual memory size (includes shared libraries, mapped files)

For a human-readable per-process view:

smem -tk

Install with sudo apt install smem.

The OOM killer

When the system runs completely out of memory (including swap), the kernel’s OOM killer terminates processes to free memory. It targets the process using the most memory.

Check OOM events:

dmesg | grep -i "out of memory"
journalctl -k | grep -i "oom"

To protect critical processes from OOM:

echo -1000 > /proc/PID/oom_score_adj

This makes the process very unlikely to be killed. Set it in the service file:

[Service]
OOMScoreAdjust=-1000

To make a process more likely to be killed:

echo 1000 > /proc/PID/oom_score_adj

Memory limits with cgroups

Control memory per service:

[Service]
MemoryLimit=512M

Or with systemd’s newer directives:

[Service]
MemoryMax=512M
MemoryHigh=400M

MemoryHigh throttles the process when it exceeds the limit. MemoryMax is a hard limit — the OOM killer activates if exceeded.

Common mistakes

Panic over low “free” memory. Low free is normal. Linux caches aggressively. Check available instead.

Ignoring swap usage. A little swap is fine. Consistent heavy swapping means you need more RAM.

Not monitoring over time. A snapshot of free shows the current state. Use vmstat 1 to see trends. Memory issues are often gradual.

Killing processes based on VmSize. VmSize includes shared libraries and mapped files. RSS is closer to actual physical memory usage.

Remarks

Linux memory management is designed to use RAM efficiently, which means most of it is always “in use” for caches. Don’t panic at low free numbers. The available column in free -h is your real indicator. For monitoring, vmstat shows trends, ps aux shows per-process usage, and the OOM killer is the last resort when everything else fails. Set up monitoring that alerts on available dropping below a threshold, not on free.

Related Posts