10.3. Memory & Disk#

10.3.1. Common Pitfalls#

1. Confusing Used vs. Available in free output

# Example:
free -h
#            total        used        free      shared  buff/cache   available
# Mem:        16Gi        8Gi        1Gi       256Mi       7Gi          7Gi

# Used=8Gi but Available=7Gi!
# Reason: buff/cache is in "used" but is freeable
# Don't panic if used seems high and available is adequate

2. du and df showing different numbers

# df: Filesystem size and allocation blocks
# du: Actual file/directory sizes
# They won't match exactly due to:
#   - Filesystem overhead
#   - Sparse files
#   - Hard links

# Always use df for "how full is the drive?"
# Use du for "which directory uses most space?"

3. Not accounting for multiple processes with shared memory

# RSS sums don't reflect actual memory
# Shared libraries can't be summed per process
ps aux | awk '{sum+=$6} END {print "Total: " sum/1024 "MB"}'
# This overcounts! Use /proc/meminfo for accuracy

4. Not checking if processes are swapped out

# A high-memory process in swap is much slower
# Check if process is using swap:
cat /proc/[pid]/smaps | grep Swap

10.3.2. Real-World Example: Resource Monitor Dashboard#

#!/bin/bash

# Simple system resource dashboard

show_dashboard() {
  clear
  echo "=== System Resource Monitor ==="
  echo "Last updated: $(date)"
  echo ""
  
  # Disk status
  echo "--- Disk Usage ---"
  df -h | grep -E '^/dev' | awk '{printf "%-20s %6s %6s %5s\n", $6, $2, $3, $5}'
  echo ""
  
  # Memory status
  echo "--- Memory Usage ---"
  free -h | awk 'NR==2 {
    printf "Total: %s | Used: %s | Available: %s\n", $2, $3, $7
  }'
  echo ""
  
  # Top processes by CPU
  echo "--- Top CPU Users ---"
  ps aux --sort=-%cpu | head -4 | tail -3 | \
    awk '{printf "%-20s %5s%%\n", $11, $3}'
  echo ""
  
  # Top processes by Memory
  echo "--- Top Memory Users ---"
  ps aux --sort=-%mem | head -4 | tail -3 | \
    awk '{printf "%-20s %5s%%\n", $11, $4}'
}

# Update every 5 seconds
while true; do
  show_dashboard
  sleep 5
done

10.3.3. Disk and Memory Alerts#

10.3.3.1. Disk Space Alert#

#!/bin/bash

# Alert if disk usage exceeds 80%
THRESHOLD=80

df -h | awk 'NR>1 {
  usage = int($5)
  if (usage > threshold) {
    print "ALERT: " $6 " is " $5 " full!"
  }
}' threshold=$THRESHOLD

10.3.3.2. Memory Usage Alert#

#!/bin/bash

# Alert if memory usage exceeds 75%
THRESHOLD=75

free | awk 'NR==2 {
  usage = int($3 / $2 * 100)
  if (usage > threshold) {
    print "ALERT: Memory usage is " usage "%"
  }
}' threshold=$THRESHOLD

10.3.3.3. Combined Monitoring Function#

check_resources() {
  local disk_warn=80
  local mem_warn=75
  
  # Check disk
  df -h | awk -v warn=$disk_warn 'NR>1 {
    used = int($5)
    if (used > warn) print "⚠ Disk: " $6 " at " $5
  }'
  
  # Check memory
  free | awk -v warn=$mem_warn 'NR==2 {
    used = int($3/$2*100)
    if (used > warn) print "⚠ Memory: " used "%"
  }'
}

check_resources

10.3.4. Process Memory with ps#

# Show memory-related columns for all processes
ps aux

# Custom format: PID, name, memory in KB
ps -o pid,comm,rss

# Memory in MB
ps -o pid,comm,rss,vsz | awk '{print $1, $2, int($3/1024), int($4/1024)}'

# Top memory consumers
ps aux --sort=-%mem | head -10

# Memory used by specific process
ps -o pid,rss,vsz -p 1234

10.3.4.1. Memory Fields in ps#

Field

Meaning

RSS

Resident Set Size (actual memory in KB)

VSZ

Virtual memory size (allocated, may not be in RAM)

%MEM

Percentage of total RAM

10.3.4.2. Practical Memory Monitoring#

#!/bin/bash

# Check memory-heavy processes
echo "Top 5 memory consumers:"
ps aux --sort=-%mem | head -6 | awk \
  '{printf "%5s %s %6s%% %8s MB\n", $2, $1, $4, int($6/1024)}'

10.3.5. Memory Usage with free and ps#

10.3.5.1. free Command#

# Show memory usage
free

# Human-readable format
free -h

# Show in MB
free -m

# Show in GB
free -g

# Continuous monitoring (update every 1 second)
free -h -s 1

10.3.5.2. Understanding free Output#

               total        used        free      shared  buff/cache   available
Mem:           7.7Gi       2.3Gi       1.8Gi      256Mi       3.6Gi       4.9Gi
Swap:          2.0Gi       0.0Gi       2.0Gi
  • total: Total memory

  • used: Memory used

  • free: Completely unused

  • available: Can be allocated to processes

  • buff/cache: Kernel buffers and caches (can be freed)

10.3.6. Directory Size with du#

The du command shows directory and file sizes:

10.3.6.1. Basic du Usage#

# Size of current directory tree
du

# Human-readable format
du -h

# Only top-level directories (max depth 1)
du -h --max-depth=1

# Total only (no breakdown)
du -sh /home

# Sort by size
du -sh /home/* | sort -hr

# Find large directories
du -h /var --max-depth=1 | sort -hr | head -10

10.3.6.2. Understanding du Output#

$ du -h --max-depth=1 /home
4.2G    /home/alice
2.1G    /home/bob
1.5G    /home/shared
7.8G    /home
  • Each directory and total size in human-readable format

  • -s: Summary only (single line)

  • -c: Include grand total line

10.3.7. Disk Usage with df#

The df command shows filesystem disk usage:

10.3.7.1. Basic df Usage#

# Show all mounted filesystems
df

# Human-readable format
df -h

# Show inode usage
df -i

# Only local filesystems (exclude network mounts)
df -l

# Show filesystem type
df -T

# Combined: human-readable + type
df -hT

10.3.7.2. Understanding df Output#

Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda1      102092920 8392496  88304424   9% /
/dev/sda2      409600        240    409360   1% /boot
tmpfs           4056088       0   4056088   0% /run
  • 1K-blocks: Total size

  • Used: Currently used

  • Available: Available to users

  • Use%: Percentage used

  • Mounted on: Where filesystem is mounted