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 memoryused: Memory usedfree: Completely unusedavailable: Can be allocated to processesbuff/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 sizeUsed: Currently usedAvailable: Available to usersUse%: Percentage usedMounted on: Where filesystem is mounted