How to Measure the Actual Memory Usage of an Application or Process
You check a process's memory usage with top or ps and see huge numbers, but you're not sure what they mean or which one represents actual memory consumption. How do you measure real memory usage?
TL;DR
For actual physical memory used by a process, check the RSS (Resident Set Size) value, which shows memory currently in RAM. Use ps aux and look at the RSS column, or use /proc/[pid]/status and check VmRSS. For a more accurate picture accounting for shared memory, use the PSS (Proportional Set Size) from /proc/[pid]/smaps. Virtual memory (VIRT/VSZ) is usually much larger and doesn't represent actual RAM usage.
Memory measurement in Linux is complex because processes share memory, map files, and use virtual memory. Understanding the different metrics helps you identify real memory issues.
Let's start by running a simple memory check:
ps aux | grep myapp
You'll see output like:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 1234 2.5 5.2 890000 54000 ? Ssl 10:23 0:15 myapp
The key columns are:
VSZ- Virtual memory size (in KB)RSS- Resident set size (in KB)%MEM- Percentage of physical RAM
But what do these numbers really mean?
Understanding Memory Metrics
Linux provides several memory measurements:
VIRT/VSZ (Virtual Memory Size):
- Total virtual memory allocated
- Includes memory not actually in RAM
- Includes shared libraries, mapped files
- Usually much larger than physical memory used
RES/RSS (Resident Set Size):
- Physical memory currently in RAM
- Includes shared libraries (counted for each process)
- Better indicator of actual memory usage
- But overstates shared memory usage
SHR (Shared Memory):
- Memory shared with other processes
- Libraries loaded by multiple processes
- Doesn't mean the process uses all of it
PSS (Proportional Set Size):
- Most accurate measure of real memory use
- Divides shared memory proportionally
- Not shown by top/ps by default
Using ps to Check Memory
Get memory info for a specific process:
# By process name
ps aux | grep myapp
# By PID
ps aux | grep 1234
# Show RSS in human-readable format
ps aux --sort -rss | head -10
This shows the top 10 processes by RSS (resident memory).
For a cleaner output with specific columns:
ps -eo pid,comm,rss,vsz | grep myapp
Or in megabytes:
ps -eo pid,comm,rss | awk '{printf "%s %s %.2f MB\n", $1, $2, $3/1024}' | grep myapp
Using top or htop
Real-time memory monitoring with top:
top
Press M to sort by memory usage. Look at the RES column for resident memory.
For better visualization, install and use htop:
sudo apt install htop # Ubuntu/Debian
htop
Press F6, select MEM% to sort by memory percentage. The display is color-coded and easier to read than top.
Checking /proc for Detailed Memory Info
The /proc filesystem provides detailed memory information:
# Replace [pid] with actual process ID
cat /proc/[pid]/status | grep -i mem
Output shows various memory metrics:
VmPeak: 945032 kB # Peak virtual memory
VmSize: 890124 kB # Current virtual memory
VmLck: 0 kB # Locked memory
VmPin: 0 kB # Pinned memory
VmHWM: 54320 kB # Peak resident memory
VmRSS: 54000 kB # Current resident memory
VmData: 123456 kB # Data segment size
VmStk: 136 kB # Stack size
VmExe: 16 kB # Executable size
VmLib: 45000 kB # Shared library memory
The most useful values:
VmRSS- Memory currently in physical RAMVmHWM- Peak memory usage (high water mark)
Getting Proportional Set Size (PSS)
PSS gives the most accurate picture by accounting for shared memory:
grep Pss /proc/[pid]/smaps | awk '{sum+=$2} END {print sum " KB"}'
This sums up the PSS values from all memory mappings. The result is typically lower than RSS because shared memory is divided among processes.
To see PSS for all processes:
# List all processes with their PSS
for pid in /proc/[0-9]*; do
if [ -f "$pid/smaps" ]; then
pss=$(grep Pss "$pid/smaps" 2>/dev/null | awk '{sum+=$2} END {print sum}')
if [ ! -z "$pss" ] && [ "$pss" -gt 0 ]; then
name=$(cat "$pid/comm" 2>/dev/null)
printf "%-20s %10d KB\n" "$name" "$pss"
fi
fi
done | sort -k2 -rn | head -10
This shows the top 10 processes by actual memory usage (PSS).
Using smem for Accurate Memory Reporting
The smem tool reports PSS and other accurate memory metrics:
# Install smem
sudo apt install smem # Ubuntu/Debian
# Show memory usage by process
smem -r
# Show summary by user
smem -u
# Show specific columns
smem -c "pid name pss rss"
smem output columns:
PSS- Proportional set size (most accurate)RSS- Resident set sizeUSS- Unique set size (memory used only by this process)
Memory Usage from Inside a Container
For Docker containers:
# Memory usage of a container
docker stats container_name --no-stream
# Detailed memory info
docker inspect container_name | grep -i memory
For a process inside a container:
# Enter the container
docker exec -it container_name sh
# Check memory inside
ps aux
cat /proc/[pid]/status | grep VmRSS
Monitoring Memory Over Time
Create a script to log memory usage:
#!/bin/bash
PID=$1
LOG_FILE="memory-log-$PID.txt"
if [ -z "$PID" ]; then
echo "Usage: $0 <pid>"
exit 1
fi
echo "Logging memory for PID $PID to $LOG_FILE"
echo "Timestamp,VmRSS (KB),VmSize (KB)" > "$LOG_FILE"
while true; do
if [ ! -d "/proc/$PID" ]; then
echo "Process $PID no longer exists"
exit 0
fi
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
VMRSS=$(grep VmRSS /proc/$PID/status | awk '{print $2}')
VMSIZE=$(grep VmSize /proc/$PID/status | awk '{print $2}')
echo "$TIMESTAMP,$VMRSS,$VMSIZE" >> "$LOG_FILE"
sleep 5
done
Run it:
chmod +x monitor-memory.sh
./monitor-memory.sh 1234
This logs memory every 5 seconds to a CSV file.
Finding Memory Leaks
To detect memory leaks, watch for steadily increasing RSS:
# Watch a specific process
watch -n 1 'ps -p 1234 -o pid,comm,rss,vsz'
Or use a script to alert on memory growth:
#!/bin/bash
PID=$1
THRESHOLD=500000 # KB
INITIAL_RSS=$(grep VmRSS /proc/$PID/status | awk '{print $2}')
while true; do
sleep 60
CURRENT_RSS=$(grep VmRSS /proc/$PID/status | awk '{print $2}')
INCREASE=$((CURRENT_RSS - INITIAL_RSS))
if [ $INCREASE -gt $THRESHOLD ]; then
echo "WARNING: Memory increased by ${INCREASE} KB"
# Send alert, restart process, etc.
fi
echo "$(date): RSS = $CURRENT_RSS KB (increase: $INCREASE KB)"
done
Memory Usage by Programming Language
Different languages report memory differently:
Python:
import psutil
import os
process = psutil.Process(os.getpid())
memory_info = process.memory_info()
print(f"RSS: {memory_info.rss / 1024 / 1024:.2f} MB")
print(f"VMS: {memory_info.vms / 1024 / 1024:.2f} MB")
Node.js:
const used = process.memoryUsage();
console.log(`RSS: ${used.rss / 1024 / 1024} MB`);
console.log(`Heap Used: ${used.heapUsed / 1024 / 1024} MB`);
console.log(`Heap Total: ${used.heapTotal / 1024 / 1024} MB`);
Go:
package main
import (
"fmt"
"runtime"
)
func main() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("Alloc = %v MB\n", m.Alloc / 1024 / 1024)
fmt.Printf("TotalAlloc = %v MB\n", m.TotalAlloc / 1024 / 1024)
fmt.Printf("Sys = %v MB\n", m.Sys / 1024 / 1024)
}
Practical Example: Web Server Memory Analysis
Analyze a web server's memory:
#!/bin/bash
# Find nginx processes
echo "=== Nginx Memory Usage ==="
ps aux | grep nginx | grep -v grep
echo ""
echo "=== Total Nginx Memory (RSS) ==="
ps aux | grep nginx | grep -v grep | awk '{sum+=$6} END {print sum " KB = " sum/1024 " MB"}'
echo ""
echo "=== Per-Process Breakdown ==="
ps -C nginx -o pid,comm,rss,vsz --sort -rss
echo ""
echo "=== Shared Memory Analysis ==="
# Get the master process PID
MASTER_PID=$(ps aux | grep 'nginx: master' | grep -v grep | awk '{print $2}')
if [ ! -z "$MASTER_PID" ]; then
PSS=$(grep Pss /proc/$MASTER_PID/smaps 2>/dev/null | awk '{sum+=$2} END {print sum}')
echo "Master process PSS: $PSS KB"
fi
When to Worry About Memory Usage
High RSS is a concern when:
- It grows continuously (memory leak)
- It exceeds available RAM (causes swapping)
- It's significantly higher than expected
- The system starts using swap heavily
High VIRT is usually fine if RSS is reasonable - processes often allocate virtual memory they never actually use.
Common Memory Issues
Issue: High memory reported but system isn't slow
- Check RSS, not VIRT
- Look at shared memory (SHR)
- Use PSS for accurate measurement
Issue: Memory grows slowly over time
- Likely a memory leak
- Monitor RSS over hours/days
- Profile the application code
Issue: Sudden memory spike
- Check recent process starts
- Look for large file operations
- Check for cache buildup
Accurately measuring memory usage requires looking at the right metrics. Focus on RSS for quick checks, PSS for accuracy, and monitor trends over time to catch leaks. Virtual memory (VIRT/VSZ) is usually not a concern unless RSS is also high.
Found an issue?