When diagnosing memory pressure on Linux systems, the key is distinguishing between different types of memory usage. The /proc/meminfo file provides the most comprehensive view:
# Sample meminfo parsing
grep -E 'MemTotal|Active|Inactive|Committed_AS|Swap' /proc/meminfo
# Output example:
MemTotal: 32887052 kB
Active: 21457368 kB
Inactive: 8273544 kB
Committed_AS: 35789124 kB
SwapTotal: 2097148 kB
SwapFree: 524288 kB
Calculating "wired" memory (actively used and not reclaimable) gives a solid baseline:
#!/bin/bash
mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
mem_active=$(grep Active /proc/meminfo | awk '{print $2}')
mem_inactive=$(grep Inactive /proc/meminfo | awk '{print $2}')
wired_kb=$((mem_total - mem_active - mem_inactive))
wired_percent=$((wired_kb * 100 / mem_total))
echo "Wired memory: ${wired_kb} kB (${wired_percent}%)"
Summing RSS (Resident Set Size) across all processes reveals actual physical memory usage:
# Sum RSS for all processes (in kB)
ps -eo rss | awk '{sum+=$1} END {print sum}'
# Alternative with detailed breakdown
ps -eo pid,rss,comm | \
awk '{sum+=$2} END {print "Total RSS:",sum" kB"}' | \
sort -k2 -nr | head -20
/proc/meminfo's Committed_AS shows memory that programs have requested (not necessarily used):
committed_as=$(grep Committed_AS /proc/meminfo | awk '{print $2}')
mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
# Calculate commit ratio
awk -v c=$committed_as -v t=$mem_total \
'BEGIN {printf "Commit ratio: %.1f%%\n", (c/t)*100}'
Combine these metrics into a comprehensive check:
#!/bin/bash
MEM_LOW_THRESHOLD=90 # Percentage threshold
# Get metrics
mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
mem_avail=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
committed_as=$(grep Committed_AS /proc/meminfo | awk '{print $2}')
swap_used=$(free | grep Swap | awk '{print $3}')
# Calculate percentages
avail_percent=$((mem_avail * 100 / mem_total))
commit_ratio=$((committed_as * 100 / mem_total))
# Evaluation
if [ $avail_percent -lt 10 ] || [ $commit_ratio -gt 150 ]; then
echo "ALERT: Memory pressure detected"
echo "Available: ${avail_percent}%, Commit Ratio: ${commit_ratio}%"
echo "Swap Used: ${swap_used} kB"
exit 1
else
echo "Memory status OK"
exit 0
fi
For containerized environments, consider these additional metrics:
# Container memory limits (cgroups v2)
cat /sys/fs/cgroup/memory.max
# Current usage
cat /sys/fs/cgroup/memory.current
# OOM events tracking
dmesg | grep -i "out of memory"
Linux memory management is complex, with dozens of metrics available in /proc/meminfo
, free
, top
, and other tools. The challenge lies in identifying which metrics truly indicate memory pressure versus those that simply show memory allocation patterns.
These are the most reliable indicators of actual memory pressure:
# Example of checking critical metrics
cat /proc/meminfo | grep -E 'MemTotal|MemFree|Buffers|Cached|Active|Inactive|SwapCached|Commit'
# Alternative using free
free -m
A robust approach combines multiple metrics into a single pressure index:
#!/bin/bash
# Calculate memory pressure score (0-100)
MEM_TOTAL=$(grep MemTotal /proc/meminfo | awk '{print $2}')
MEM_AVAILABLE=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
SWAP_TOTAL=$(grep SwapTotal /proc/meminfo | awk '{print $2}')
SWAP_FREE=$(grep SwapFree /proc/meminfo | awk '{print $2}')
MEM_PRESSURE=$((100 - (MEM_AVAILABLE * 100 / MEM_TOTAL)))
SWAP_USAGE=$((100 - (SWAP_FREE * 100 / SWAP_TOTAL)))
PRESSURE_SCORE=$(( (MEM_PRESSURE * 70 + SWAP_USAGE * 30) / 100 ))
echo "Memory Pressure Score: ${PRESSURE_SCORE}%"
Use these guidelines for interpreting memory status:
- < 70%: Healthy (no action needed)
- 70-85%: Warning (monitor closely)
- > 85%: Critical (immediate action required)
When overall memory appears tight, examine individual processes:
# Show top memory-consuming processes
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -n 10
# Detailed RSS analysis
awk '{print $1}' /proc/*/status 2>/dev/null | grep -i vmsize | sort -n -k2 | tail -n 10
For production systems, implement this Python monitoring script:
import psutil
import time
def check_memory_pressure():
mem = psutil.virtual_memory()
swap = psutil.swap_memory()
pressure = {
'percent_used': mem.percent,
'available_gb': mem.available / (1024**3),
'swap_used': swap.percent,
'pressure_score': (mem.percent * 0.7) + (swap.percent * 0.3)
}
return pressure
while True:
status = check_memory_pressure()
print(f"Memory Status: {status}")
if status['pressure_score'] > 85:
print("ALERT: High memory pressure detected!")
time.sleep(60)