Linux free Command: A Deep Dive into Memory Monitoring and OOM Troubleshooting#

Server OOM again? I spent hours staring at top trying to figure out where the memory went. Turns out, free is the right tool for memory analysis. Here’s what I learned about its internals and practical usage.

Understanding the Four Lines of Output#

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           15Gi       8.5Gi       1.2Gi       256Mi       5.3Gi       5.8Gi
Swap:         2.0Gi       512Mi       1.5Gi

Many people get confused: why doesn’t used + free equal total? And what’s available?

The key is buff/cache. Linux uses idle memory for buffer cache and page cache to speed up file I/O. So:

  • free: Completely unused memory
  • buff/cache: Memory used for caching (reclaimable)
  • available: Memory programs can actually allocate (free + reclaimable cache)

To judge if memory is tight, look at available, not free.

/proc/meminfo: Where free Gets Its Data#

free reads from /proc/meminfo:

$ head -20 /proc/meminfo
MemTotal:       16384000 kB
MemFree:         1228800 kB
MemAvailable:    6029312 kB
Buffers:          524288 kB
Cached:          5242880 kB
SwapCached:            0 kB
Active:          4194304 kB
Inactive:        3145728 kB

The core logic of free is parsing these fields:

// Simplified free command logic
void print_meminfo() {
    FILE *fp = fopen("/proc/meminfo", "r");
    unsigned long mem_total, mem_free, buffers, cached;

    // Parse line by line
    while (fgets(line, sizeof(line), fp)) {
        if (sscanf(line, "MemTotal: %lu kB", &mem_total));
        else if (sscanf(line, "MemFree: %lu kB", &mem_free));
        else if (sscanf(line, "Buffers: %lu kB", &buffers));
        else if (sscanf(line, "Cached: %lu kB", &cached));
    }

    // Calculate
    unsigned long used = mem_total - mem_free - buffers - cached;
    unsigned long buff_cache = buffers + cached;

    printf("Mem: %lu %lu %lu %lu %lu\n",
           mem_total, used, mem_free, buff_cache, ...);
}

The available calculation is more complex, involving the MemAvailable field (kernel 3.14+) or estimating reclaimable memory.

Common Parameters#

-h: Human-Readable Format#

$ free -h
Mem:   15Gi  8.5Gi  1.2Gi  256Mi  5.3Gi  5.8Gi

Automatically converts units (K/M/G/T), smarter than -m (MB) or -g (GB).

-b/-k/-m/-g: Specify Units#

$ free -m  # Display in MB
$ free -g  # Display in GB
$ free -b  # Display in bytes

Use -b for monitoring scripts to calculate percentages.

-s N: Continuous Monitoring#

$ free -s 1  # Refresh every second
$ free -s 5 -c 10  # Refresh every 5 seconds, 10 times total

Use -c to limit iterations and avoid infinite loops.

-t: Show Total#

$ free -t
              total        used        free      shared  buff/cache   available
Mem:        16384000     8847360     1257472      262144     6279168     6029312
Swap:        2097152      524288     1572864
Total:      18481152     9371648     2830336

Adds a Total row combining Mem and Swap.

-w: Wide Output, Separate Buffer and Cache#

$ free -w
              total        used        free      shared     buffers       cache   available
Mem:        16384000     8847360     1257472      262144      524288     5754880     6029312

Buffers is block device cache, cache is filesystem cache. Separating them gives more clarity.

Practical Scenarios#

1. Detecting Memory Pressure#

$ free -h
Mem:   15Gi  14Gi  512Mi  256Mi  512Mi  400Mi

available is only 400Mi - memory is tight but not yet OOM. Time to scale or optimize.

2. Swap Usage Analysis#

$ free -h
Swap:  2.0Gi  1.8Gi  200Mi

Swap at 90% means severe memory shortage. The system is thrashing, performance will tank.

3. Observing Cache Effects#

# First read of large file
$ time cat 10GB.log > /dev/null
real    0m45.123s

# Second read (cache hit)
$ time cat 10GB.log > /dev/null
real    0m2.456s

# Observe cache growth
$ free -h
buff/cache increased from 5.3Gi to 10.2Gi

Linux automatically uses idle memory for caching to accelerate file access.

4. Manually Dropping Cache#

# Drop page cache
$ echo 1 > /proc/sys/vm/drop_caches

# Drop dentries and inodes
$ echo 2 > /proc/sys/vm/drop_caches

# Drop all cache
$ echo 3 > /proc/sys/vm/drop_caches

Warning: Avoid in production; it hurts performance. Sync first:

$ sync && echo 3 > /proc/sys/vm/drop_caches

5. Monitoring Script Example#

#!/bin/bash
# Memory monitoring script

THRESHOLD=90  # Memory usage threshold

while true; do
    MEM_INFO=$(free | grep Mem)
    TOTAL=$(echo $MEM_INFO | awk '{print $2}')
    USED=$(echo $MEM_INFO | awk '{print $3}')

    PERCENT=$(echo "scale=2; $USED * 100 / $TOTAL" | bc)

    if (( $(echo "$PERCENT > $THRESHOLD" | bc -l) )); then
        echo "$(date): Memory usage ${PERCENT}% exceeds threshold!"
        # Send alert
    fi

    sleep 60
done

Common Misconceptions#

1. Low free means memory shortage#

Actually, Linux’s design philosophy is “idle memory is wasted”. Low free means cache is being utilized.

2. High used means memory pressure#

Wrong. used includes buff/cache, which can be released immediately.

The right metric: Look at available, not free or used.

3. Any swap usage is a problem#

Not necessarily. Minor swap usage is normal, like programs dormant on disk. The key is whether swap is growing.

free vs Other Tools#

Tool Advantage Use Case
free Quick overview Daily checks
top/htop Real-time process sorting Find memory hogs
vmstat Detailed memory stats Performance analysis
/proc/meminfo Complete memory info Deep diagnostics
smem Process actual memory (PSS) Accurate accounting

smem uses PSS (Proportional Set Size), more accurate than top’s RES:

$ smem -t -k -s rss
  PID User     Command     Swap  USS    PSS    RSS
12345 nginx    nginx       0     45M    52M    68M

Summary#

free is simple, but reading it requires understanding Linux memory management:

  • Check available to judge memory pressure
  • buff/cache is good - don’t panic at low free
  • Continuously growing swap is the danger signal
  • Use /proc/meminfo for deep diagnostics

Next time you face OOM, start with free -h for the big picture, then use smem or htop to find specific processes.


Related: Linux df Disk Space Monitoring | Linux du Directory Size Statistics