Understanding Linux Memory Metrics: VIRT, RES, SHR, and RSS Explained for Developers


1 views

When monitoring process memory usage in Linux, several key metrics appear in tools like ps and top:

# Sample ps output headers
$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

VIRT (called VSZ in ps) represents the total address space a process can potentially access:

  • Includes memory-mapped files and shared libraries
  • Shows allocated but not necessarily used memory
  • Example: A process might show 500MB VIRT while only using 50MB physically

RES (called RSS in ps) shows actual physical RAM being used:

# Get RSS for a specific process
$ ps -p $(pidof nginx) -o rss=
123456  # in kilobytes

Note: This includes memory shared with other processes (counted multiple times)

SHR represents the portion of RES that's shared with other processes:

  • Includes shared libraries and memory-mapped files
  • Critical for understanding true memory pressure
  • Example: 10 Python processes might share 50MB libraries (counted as SHR)

Here's how to extract memory info programmatically:

#!/bin/bash
# Monitor memory usage of a process
PID=$1
echo "Memory usage for PID $PID:"
echo "VIRT: $(ps -p $PID -o vsz=) KB"
echo "RES:  $(ps -p $PID -o rss=) KB"
echo "SHR:  $(pmap -x $PID | grep total | awk '{print $4}') KB"

Key relationships between these metrics:

VIRT ≥ RES ≥ SHR

When analyzing memory usage:

  1. Check VIRT for memory leaks (growing over time)
  2. Monitor RES for actual physical memory pressure
  3. Consider SHR when multiple similar processes run

For deeper investigation, use smem for proportional set size (PSS):

$ smem -t -k -P "chrome"
PID User     Command                         Swap      USS      PSS      RSS 
1234 user     chrome                              0    125.6    135.2    210.4

PSS accounts for shared memory proportionally (more accurate for multiple processes)


When monitoring process memory usage in Linux, these are the key metrics you'll encounter:

  • VIRT/vsize: Total virtual memory used (code+data+shared+swap)
  • RES/rss: Resident Set Size - physical RAM actually used
  • SHR: Shared memory portion of RES (shared libraries, etc.)

The ps aux and top commands display overlapping but differently named metrics:

# Sample ps output headers:
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# 
# Equivalent top columns:
# PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

To see all memory metrics for a specific process (e.g., nginx):

ps -p $(pgrep nginx) -o pid,vsz,rss,sz,share

Output interpretation:

  PID    VSZ   RSS    SZ  SHARE
12345  274004  9860  68501   2100

For developers needing detailed analysis, consider these tools:

  • pmap -x [pid] - Shows memory mapping details
  • smem -p -P "process_name" - Proportional memory reporting

When tracking a memory leak, monitor RES growth over time:

while true; do 
  ps -p $YOUR_PID -o rss= | awk '{print strftime("%T"), $1}'
  sleep 5
done

Key indicators:

  • Growing RSS with stable workload = potential leak
  • High VIRT but low RSS = normal (memory-mapped files)

Remember that:

  • SHR memory is shared between processes (e.g., libc)
  • High VIRT alone isn't problematic - modern systems use demand paging
  • RSS should be compared to available memory, not total