When working with vmstat
, it's crucial to understand that its memory columns represent different aspects of memory utilization:
swpd - Amount of virtual memory used (KB)
free - Idle memory (KB)
buff - Memory used as buffers (KB)
cache - Memory used as cache (KB)
The main confusion arises because vmstat
doesn't directly show total physical memory. Unlike top
or free
, you need to calculate it:
total_memory = free + buff + cache + used_memory
However, vmstat
doesn't display the "used_memory" directly. Here's how to derive it:
From your example output:
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 139728 45396 199128 1236360 1 2 4 622 3 1 51 4 43 2 0
Here's the calculation script:
#!/bin/bash
# Get memory info from vmstat
vmstat_output=$(vmstat -s)
# Extract values
total_memory=$(echo "$vmstat_output" | grep "total memory" | awk '{print $1}')
used_memory=$(echo "$vmstat_output" | grep "used memory" | awk '{print $1}')
# Calculate percentage
memory_usage_percentage=$(echo "scale=2; ($used_memory/$total_memory)*100" | bc)
echo "Memory Usage: ${memory_usage_percentage}%"
For more accurate results, use vmstat -s
which provides memory statistics in a parseable format:
vmstat -s | grep -E "total memory|used memory"
Sample output:
4059616 K total memory
3965504 K used memory
45396 K free memory
199128 K buffer memory
1236360 K cache memory
The discrepancy occurs because:
top
includes kernel memory in its calculationsvmstat
reports raw memory statistics without kernel allocations- Buffers and cache handling differs between tools
For continuous monitoring, use this script that calculates memory usage percentage:
#!/bin/bash
while true; do
vmstat_data=$(vmstat -s)
total=$(echo "$vmstat_data" | awk '/total memory/ {print $1}')
used=$(echo "$vmstat_data" | awk '/used memory/ {print $1}')
perc=$(echo "scale=2; $used*100/$total" | bc)
echo "$(date) - Memory Usage: $perc%"
sleep 5
done
Remember that Linux uses available memory aggressively for caching. High memory usage shown in vmstat
might not indicate a real problem - the cache can be freed when applications need memory.
When analyzing memory usage through vmstat
, it's crucial to understand the exact meaning of each memory-related field:
-----------memory----------
swpd free buff cache
139728 45396 199128 1236360
- swpd: Amount of swap memory used (in kB)
- free: Idle memory (unallocated RAM)
- buff: Memory used as buffers
- cache: Memory used as page cache
The key observation is that vmstat
doesn't directly display total physical memory. While you might think to sum swpd + free + buff + cache
, this approach has flaws:
# This naive calculation would be incorrect:
swpd + free + buff + cache = 1620612 kB (~1.62 GB)
# While 'top' shows 4059616 kB (~4.06 GB) total
To accurately calculate memory usage percentage from vmstat
, you need:
- Total physical memory (must be obtained separately)
- Correct formula for used memory
Here's a Bash script that combines vmstat
with free
to get the percentage:
#!/bin/bash
# Get total memory
TOTAL_MEM=$(free -k | awk '/Mem:/ {print $2}')
# Get memory stats from vmstat
read SWPD FREE BUFF CACHE < <(vmstat -s | awk '
/used swap/ {swpd=$1}
/free memory/ {free=$1}
/buffer memory/ {buff=$1}
/cache/ {cache=$1}
END {print swpd, free, buff, cache}')
# Calculate used memory (excluding buffers/cache as they're reclaimable)
USED_MEM=$((TOTAL_MEM - FREE - BUFF - CACHE))
# Calculate percentage
MEM_USAGE_PERCENT=$((USED_MEM * 100 / TOTAL_MEM))
echo "Memory Usage: ${MEM_USAGE_PERCENT}%"
Another approach using /proc/meminfo
for total memory:
# Get total memory from /proc
TOTAL=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
# Get available memory from vmstat
AVAILABLE=$(vmstat -s | awk '/free memory/ {print $1}')
USED=$((TOTAL - AVAILABLE))
PERCENT=$((USED * 100 / TOTAL))
echo "Used: ${PERCENT}%"
The fundamental limitation is that vmstat
was designed primarily for monitoring system activity and performance statistics, not for comprehensive memory reporting. For accurate memory percentage calculations, you need to:
- Combine with other tools (
free
,/proc/meminfo
) - Understand what constitutes "used" vs "available" memory
- Account for buffers and cache differently depending on your needs
For enterprise monitoring systems, consider this robust implementation:
#!/bin/bash
# Returns memory usage percentage from vmstat-like sources
get_mem_stats() {
# Try various methods to get memory info
if [ -f /proc/meminfo ]; then
read _ TOTAL _ FREE _ BUFF _ CACHE _ < <(awk '
/MemTotal/ {t=$2}
/MemFree/ {f=$2}
/Buffers/ {b=$2}
/Cached/ {c=$2}
END {print t, f, b, c}' /proc/meminfo)
elif which free >/dev/null; then
read TOTAL USED FREE SHARED BUFF CACHE < <(free -k | awk '/Mem:/ {print $2,$3,$4,$5,$6,$7}')
else
echo "Error: No memory info available" >&2
exit 1
fi
}
get_mem_stats
# Calculate used memory (adjust formula as needed)
USED=$((TOTAL - FREE - BUFF - CACHE))
PERCENT=$((USED * 100 / TOTAL))
echo "$PERCENT"