Check memory in Linux with free (overview), vmstat (virtual memory stats), top/htop (per-process), or /proc/meminfo (raw data). The right pick depends on what you’re trying to understand.
Table of contents
- The free command
- The vmstat command
- The top/htop for per-process memory
- The /proc/meminfo file
- OOM killer
- What usually breaks
- The memory profiling tools
- The NUMA memory
- FAQ
The free command
The right tool for a quick overview:
$ free -h
The -h flag shows human-readable sizes (GB, MB). The output:
total: Total physical memory.used: Memory used by applications.free: Memory that is completely unused.shared: Memory shared between processes.buff/cache: Memory used by the kernel for buffers and page cache.available: Memory available for new applications (free + reclaimable).
The team that sees low free but high available has memory used for page cache; the kernel will reclaim it when needed. The team that sees low available has memory pressure.
The vmstat command
The right tool for virtual memory stats:
$ vmstat 1
The 1 updates every second. The columns that matter:
si/so: Swap-in and swap-out (KB/s). Non-zero means the system is swapping.bi/bo: Block-in and block-out (blocks/s). High values mean disk I/O.us/sy/id/wa: User, system, idle, iowait CPU percentages.
The team that sees non-zero si/so has memory pressure; the system is using swap, which is much slower than RAM.
The top/htop for per-process memory
The right tool for finding the process using memory:
$ top
Sort by memory (press M). The columns:
%MEM: Percentage of total memory.VIRT: Virtual memory size (all memory the process can address).RES: Resident memory (physical memory the process is using).SHR: Shared memory.
The team that finds a process using 80% of memory has a memory leak or an undersized instance. The fix depends on the process.
The /proc/meminfo file
The right tool for raw data:
$ cat /proc/meminfo
The output has 50+ fields. The fields that matter:
MemTotal: Total physical memory.MemFree: Memory not used.MemAvailable: Memory available for new allocations.Buffers: Kernel buffer cache.Cached: Page cache.SwapTotal/SwapFree: Swap space.
The team that scripts memory monitoring reads /proc/meminfo. The team that uses Prometheus node_exporter gets this data with historical graphs.
OOM killer
When the system runs out of memory, the kernel OOM killer fires. The killed process shows up in dmesg:
$ dmesg | grep -i 'out of memory'
The team that sees OOM kills has memory pressure. The fix: add memory, find the leak, or set memory limits on the offending process.
What usually breaks
The four pitfalls:
- Confusing
freeandavailable.freeis unused memory;availableis memory that can be reclaimed. The team that watchesfreepanics; the team that watchesavailablehas the right metric. - Swapping is invisible. The team that sees slow performance but doesn’t check
vmstathas a swap problem they don’t know about. - Page cache uses memory. The team that sees high
usedbut the system is fast has page cache memory, which is fine. - Container memory limits. The team that runs in a container with a 1 GB memory limit has the kernel OOM-kill processes at 1 GB, regardless of host memory.
The memory profiling tools
Beyond free and vmstat:
valgrind. Memory debugging tool. valgrind --tool=memcheck ./myapp shows memory leaks, use-after-free, uninitialized reads. The right tool for C/C++ apps with memory bugs.
AddressSanitizer (ASan). Compile with -fsanitize=address for runtime memory error detection. Faster than valgrind; built into GCC and Clang.
heaptrack. Memory profiler for C++. Shows allocations and the call stacks that made them.
tracemalloc (Python). Built-in Python memory profiler. import tracemalloc; tracemalloc.start() enables tracking. The team that has a Python memory leak uses tracemalloc.
memory_profiler (Python). Decorator-based memory usage per line. @profile def my_func() shows memory usage line by line.
pprof (Go). Built-in memory profiler. go tool pprof http://localhost:6060/debug/pprof/heap opens the interactive profiler.
The team that uses the right profiler for the language has the deepest insight into memory usage. The team that only uses free has a high-level view.
The NUMA memory
On multi-socket systems, NUMA matters for memory:
- Local memory. Memory on the same NUMA node as the CPU. Fast access.
- Remote memory. Memory on a different NUMA node. Slower access (latency + bandwidth penalty).
The right way to handle NUMA:
- Bind memory to NUMA node.
numactl --membind=0 ./myappallocates memory only on NUMA node 0. - Interleave.
numactl --interleave=all ./myappinterleaves memory across all nodes. The right choice for memory-intensive workloads.
The team that uses NUMA-aware memory allocation has consistent performance for memory-intensive workloads. The team that ignores NUMA has unpredictable performance depending on which CPU the process is scheduled on.
FAQ
What’s the difference between free and available memory?
free is unused. available is unused + reclaimable (page cache, etc.). The team that watches available has the right metric.
How do I find the process using the most memory?
top sorted by memory (press M). The team that sees a runaway process kills it with k in top.
What is swap?
Disk space used as overflow when physical memory is full. Slow. The team that sees non-zero swap activity in vmstat has memory pressure.
How do I find OOM kills?
dmesg | grep -i 'out of memory'. The team that sees OOM kills has memory pressure; the fix is to add memory or limit the offending process.
What’s the difference between RSS and VSZ?
RSS (Resident Set Size) is the physical memory the process is using. VSZ (Virtual Size) is the total virtual memory the process has allocated. RSS is what matters for memory pressure; VSZ is mostly meaningless.
How do I find a memory leak in my application?
Use the language-appropriate profiler. For C/C++: valgrind or ASan. For Python: tracemalloc. For Go: pprof. For Java: VisualVM or JFR. The team that uses the right tool finds the leak in minutes; the team that guesses spends hours.
What causes high cache usage?
Normal kernel behavior. The kernel uses free RAM for the page cache (file contents) and buffer cache (block device data). When applications need memory, the kernel reclaims cache automatically. The team that sees high cache and interprets it as a leak is mistaken.
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: