Memory Management and Swap Optimization
Memory management fundamentally impacts system performance, with inefficient memory policies causing thrashing, latency spikes, and reduced throughput. Linux provides sophisticated memory management controls including swappiness tuning, page cache policies, and swap configuration. This guide covers optimizing memory utilization for specific workload patterns and avoiding common memory management pitfalls.
Table of Contents
- Memory Management Fundamentals
- Swappiness Configuration
- Page Cache Tuning
- OOM Killer Configuration
- Swap File Management
- zswap and Compressed Swap
- Huge Pages
- Memory Monitoring
- Conclusion
Memory Management Fundamentals
Memory Hierarchy
# Linux memory allocation hierarchy:
# 1. Page cache (recently accessed files)
# 2. Application memory (heap, stack)
# 3. Swap (disk-based overflow)
# View current memory usage
free -h
# Detailed memory breakdown
cat /proc/meminfo | head -20
# Memory per process
ps aux | head -5
# RSS: Resident Set Size (actual RAM used)
# VSZ: Virtual memory size (allocated but not all in RAM)
Memory Pressure
# Check memory pressure metrics
cat /proc/pressure/memory
# Output shows:
# some: Time tasks waited for memory
# full: Time system couldn't allocate memory
# Monitor real-time memory pressure
watch -n 1 'cat /proc/pressure/memory'
Swappiness Configuration
Understanding Swappiness
# Current swappiness value (0-100)
cat /proc/sys/vm/swappiness
# Higher values (default 60):
# - More aggressive swap usage
# - Better for desktop (interactive response)
# - Problematic for servers (latency spikes)
# Lower values (0-30):
# - Keep data in RAM
# - Better for servers and databases
# - May hit OOM faster
# Zero (not recommended in current kernels):
# - Historically disabled swap
# - Causes OOM kills instead of graceful degradation
Swappiness Tuning
# Check current swappiness
sysctl vm.swappiness
# Adjust swappiness for server workloads
sudo sysctl -w vm.swappiness=10
# More aggressive for databases needing RAM
sudo sysctl -w vm.swappiness=5
# Extreme case (emergency only)
sudo sysctl -w vm.swappiness=1
# Verify changes
sysctl vm.swappiness
# Make persistent
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.d/99-memory-tuning.conf
sudo sysctl -p /etc/sysctl.d/99-memory-tuning.conf
Swappiness in Practice
# Monitor swap usage with different swappiness settings
watch -n 1 'free -h && echo "---" && cat /proc/sys/vm/swappiness'
# Identify swap pressure
grep Swap /proc/meminfo
# Check swap I/O activity
vmstat 1
# Watch for increased page faults
grep pgfault /proc/stat
# Detect swap thrashing
watch -n 1 'grep -E "pswpin|pswpout" /proc/vmstat'
Page Cache Tuning
Cache Pressure
# View current cache pressure
cat /proc/sys/vm/cache_pressure
# Default 100: Normal cache behavior
# 0-50: Increase cache retention
# 100: Balanced behavior
# 200+: Aggressively drop cache
# Increase cache retention for workloads benefiting from caching
sudo sysctl -w vm.cache_pressure=50
# Aggressively drop cache for working-set workloads
sudo sysctl -w vm.cache_pressure=200
# Application-specific tuning
# Database with large buffer pool: lower cache_pressure
# High-throughput streaming: higher cache_pressure
Memory Reclaim Behavior
# File cache drop behavior
cat /proc/sys/vm/dirty_ratio # Percentage of memory to flush
cat /proc/sys/vm/dirty_background_ratio
# Increase dirty ratio for high-throughput writes
sudo sysctl -w vm.dirty_ratio=20 # Default 20%
sudo sysctl -w vm.dirty_background_ratio=5 # Default 10%
# Reduce for real-time sensitivity
sudo sysctl -w vm.dirty_ratio=5
sudo sysctl -w vm.dirty_background_ratio=2
# Timeout for dirty pages (centiseconds)
cat /proc/sys/vm/dirty_expire_centisecs # Default 3000 = 30 seconds
OOM Killer Configuration
Understanding OOM Killer
# OOM killer activated when memory completely exhausted
# Selects and kills process to free memory
# Monitor OOM events
dmesg | grep -i "out of memory"
# Check system logs
journalctl -u kernel --grep="OOM"
# Current OOM killer state
sysctl vm.oom_dump_tasks
# Panic on OOM (system reboot instead of kill)
sudo sysctl -w vm.panic_on_oom=1
OOM Score Adjustment
# View process OOM score
cat /proc/*/oom_score | sort -n | tail -5
# Lower OOM score = less likely to be killed
# Can be negative (0-15)
# Adjust for specific process
echo -500 > /proc/$(pgrep mysql)/oom_score_adj
# Disable OOM killer for critical process
echo -1000 > /proc/$(pgrep critical_app)/oom_score_adj
# Make process more killable (emergency cleanup)
echo 500 > /proc/$(pgrep cleanup_worker)/oom_score_adj
# Persistent OOM score via systemd
# Add to service file:
# OOMScoreAdjust=-500
Swap File Management
Creating Swap Files
# Check current swap
swapon --show
# Create swap file
sudo dd if=/dev/zero of=/swapfile bs=1G count=4
# Secure swap file (root only)
sudo chmod 600 /swapfile
# Format as swap
sudo mkswap /swapfile
# Enable swap
sudo swapon /swapfile
# Verify
swapon --show
# Enable at boot (add to /etc/fstab)
echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab
# Check fstab syntax
sudo mount -a
Swap Priority
# Check swap priorities
swapon --show
# Add second swap with priority
sudo swapon --priority 10 /swapfile2
# Or via fstab (priority is option)
# /swapfile none swap sw,priority=10 0 0
# Higher priority: used first
# Lower priority: used as overflow
# Monitor swap selection
watch -n 1 'grep -E "pswpin|pswpout" /proc/vmstat'
zswap and Compressed Swap
zswap Configuration
# Check zswap availability
grep -i zswap /boot/config-$(uname -r)
# Load zswap module
sudo modprobe zswap
# Configure zswap parameters
sudo sysctl -w vm.zswap.enabled=1
# zswap memory pool size (default 20% of RAM)
cat /sys/module/zswap/parameters/max_pool_percent
echo 30 | sudo tee /sys/module/zswap/parameters/max_pool_percent
# Compression algorithm (default lzo)
cat /sys/module/zswap/parameters/compressor
# Options: lzo, lz4, zstd (if compiled)
# Compression pool (default z3fold)
cat /sys/module/zswap/parameters/zpool
zswap vs Physical Swap
# zswap advantages:
# - Compressed memory in RAM (2-4x compression typical)
# - Faster than disk swap
# - Reduces swap I/O
# Disadvantages:
# - Uses CPU for compression
# - Reduces available application memory
# - Not suitable for swapping massive amounts
# Hybrid approach:
# - Enable zswap for burst overcommit
# - Have disk swap for sustained overflow
# - Balances latency and capacity
Huge Pages
Enabling Huge Pages
# Check huge page configuration
cat /proc/meminfo | grep -i huge
# Check available huge page sizes
grep . /sys/kernel/mm/hugepages/*/nr_hugepages
# Allocate 2MB huge pages
echo 512 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
# Allocate 1GB huge pages
echo 4 | sudo tee /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
# Persistent configuration via sysctl
echo "vm.nr_hugepages=512" | sudo tee -a /etc/sysctl.d/hugepages.conf
sudo sysctl -p /etc/sysctl.d/hugepages.conf
Application Huge Page Support
# Database (MongoDB/Redis) with huge pages
# Usually requires explicit configuration:
# Redis configuration
# In redis.conf:
# config set maxmemory-policy noeviction
# Start with huge pages
sudo numactl --cpunodebind=0 --membind=0 redis-server --maxmemory 16gb
# Monitor huge page usage
watch -n 1 'cat /proc/meminfo | grep Huge'
Memory Monitoring
Real-time Memory Monitoring
# Overall memory usage
free -h
# Detailed memory breakdown
cat /proc/meminfo
# Memory pressure stall information
watch -n 1 'cat /proc/pressure/memory'
# Per-process memory
ps aux --sort=-%mem | head -10
# Virtual memory statistics
vmstat 1
# Page faults and swapping
watch -n 1 'grep -E "pgfault|pswpin|pswpout" /proc/vmstat'
Memory Profiling
# Monitor specific process memory
watch -n 1 'ps aux | grep mysql'
# Detailed process memory map
cat /proc/$(pgrep mysql)/maps | head -20
# Memory usage per library
cat /proc/$(pgrep mysql)/smaps | grep -i "Size"
# Cache statistics
cat /proc/meminfo | grep -E "Buffers|Cached"
# Free memory percentage
free | awk '/Mem/ {printf "%.2f%% free\n", $NF/$2 * 100}'
Conclusion
Linux memory management directly impacts system stability, latency, and throughput. By tuning swappiness, managing swap appropriately, configuring huge pages, and understanding OOM behavior, infrastructure teams prevent performance degradation and ensure predictable system behavior. Different workloads require different memory policies; optimization requires understanding specific application requirements and monitoring behavior under realistic load. Combined with storage I/O tuning and CPU optimization, memory management optimization creates foundation for high-performance infrastructure.


