Step 1 — Assess overall memory status
Bash
# Overall memory status
free -h
# Mem: total=16G, used=14G, free=500M, buff/cache=2G, available=1G
# available is what matters — actually usable memory
# Detailed information
cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable|Cached|Buffers|SwapTotal|SwapFree"
# Watch memory changes over time
watch -n 5 'free -h'
# Check swap activity with vmstat
vmstat 5 10
# If the si/so columns are not consistently 0, memory is insufficientStep 2 — Identify memory-consuming processes
Bash
# Top 10 by memory
ps aux --sort=-%mem | head -11
ps aux --sort=-rss | awk '{print $2, $4, $6, $11}' | head -11
# Memory of a specific process
ps -p 1234 -o pid,rss,vsz,cmd
# RSS: actual resident memory (KB)
# VSZ: virtual memory size (includes shared libraries)
# Observe memory trend with pidstat
pidstat -r -p 1234 5 12 # 5-second interval, 1 minuteStep 3 — Analyze the process memory map
Bash
# pmap — memory mapping summary
sudo pmap -x 1234
# RSS total is actual usage
sudo pmap -x 1234 | tail -1
# /proc/PID/smaps — detailed analysis
sudo cat /proc/1234/smaps | awk '
/^Private_Dirty/ { pd += $2 }
/^Shared_Dirty/ { sd += $2 }
END { printf "Private Dirty: %d KB\nShared Dirty: %d KB\n", pd, sd }
'
# smaps_rollup — summary (kernel 4.14+)
sudo cat /proc/1234/smaps_rollup
# Check heap size
sudo cat /proc/1234/status | grep -E "VmRSS|VmHeap|VmPeak"Step 4 — Track memory leaks by language
C / C++ — Valgrind
Bash
sudo apt install -y valgrind
# Memory leak check
valgrind --leak-check=full \
--show-leak-kinds=all \
--track-origins=yes \
--verbose \
./myprogram 2>&1 | tee valgrind.log
# Key output
# "definitely lost": definite leak
# "indirectly lost": indirect leak
# "possibly lost": possible leakC / C++ — AddressSanitizer (fast compile-time check)
Bash
# Enable at compile time
gcc -fsanitize=address -g -O1 myprogram.c -o myprogram
./myprogram # Automatically reports on leakPython
Python
import tracemalloc
tracemalloc.start()
# Code to analyze
do_something()
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
print(stat)Node.js
Bash
# Compare snapshots with heapdump
node --expose-gc server.js
# Connect Chrome DevTools
node --inspect server.js
# Memory profile in chrome://inspectStep 5 — Check the OOM killer
Bash
# Check whether a process was killed by OOM
dmesg | grep -i "oom|killed process|out of memory"
sudo journalctl -k | grep -i oom
# Check OOM score (higher = killed first)
cat /proc/1234/oom_score
# Protect an important process from OOM
echo -1000 | sudo tee /proc/1234/oom_score_adjStep 6 — Temporary mitigation
Bash
# Drop page cache
sync; echo 1 | sudo tee /proc/sys/vm/drop_caches
# Drop slab cache as well
sync; echo 3 | sudo tee /proc/sys/vm/drop_caches
# Add swap (temporary)
sudo dd if=/dev/zero of=/swapfile bs=1G count=4
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfileEditorial note
AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us
Topic-related official docs (auto-linked · not per-claim sources)Linux man pages ↗
Questions & answers
Ask a question about this guide. We'll review and reply.