Skip to main content

Overview

Memory Monitor identifies the process consuming the most memory by scanning the /proc filesystem and reading memory statistics from each running process. This allows you to quickly identify memory-intensive applications.

Understanding VmRSS

VmRSS (Virtual Memory Resident Set Size) is the amount of memory that a process is actually using in physical RAM. This is the most important metric for understanding a process’s real memory footprint.
VmRSS represents the portion of a process’s memory that resides in RAM, excluding swapped-out pages. This is the “real” memory usage that impacts system performance.

VmRSS vs Other Memory Metrics

  • VmSize: Total virtual memory allocated to the process (includes swapped and unmapped memory)
  • VmRSS: Only the memory currently in physical RAM
  • Why VmRSS matters: A process can allocate gigabytes of virtual memory but only use megabytes of physical RAM. VmRSS shows the actual impact on your system.
  • VmRSS: Counts all resident memory, including shared libraries fully
  • PSS: Divides shared memory proportionally among processes
  • Why use VmRSS: It’s simpler to calculate and available in /proc/[pid]/status without additional computation

Process Scanning Implementation

Discovering Running Processes

The /proc directory contains numbered subdirectories for each running process. The ListDirectory() function scans these directories:
process_analyzer.py
def ListDirectory() -> list[str, str] | None:
    list_directory: list[str] = os.listdir("/proc")
    pids = [pid for pid in list_directory if pid.isdigit()]
This approach:
  • Lists all entries in /proc using os.listdir()
  • Filters for PIDs by checking if each directory name is numeric using isdigit()
  • Creates a list of valid process IDs to analyze
The /proc directory contains both process directories (named with PIDs) and system information files (like meminfo, cpuinfo). The isdigit() check ensures we only process actual process directories.

Tracking Maximum Memory Usage

The function maintains variables to track the process with the highest VmRSS:
process_analyzer.py
max_vmrrs: int = 0
max_pid: str = ""
max_process_name: str = ""

Reading Process Status Files

For each process, Memory Monitor reads the /proc/[pid]/status file, which contains detailed process information:
process_analyzer.py
for pid in pids:
    status_path = os.path.join("/proc", pid, "status")
    try:
        with open(status_path, "r") as f:
            vmrrs = 0
            for line in f:
                if line.startswith("Name:"):
                    max_process_name = line.strip().split()[1]
                if line.startswith("VmRSS:"):
                    vmrrs = int(line.strip().split()[1])
                    if vmrrs > max_vmrrs:
                        max_vmrrs = vmrrs
                        max_pid = pid
The parser:
  • Opens each status file using the constructed path /proc/[pid]/status
  • Reads line by line to find the process name and VmRSS value
  • Extracts the process name from lines starting with Name:
  • Extracts VmRSS value from lines starting with VmRSS:
  • Compares and updates the maximum VmRSS found so far
VmRSS values in /proc/[pid]/status are in kilobytes (kB). Some processes may not have a VmRSS entry if they haven’t allocated any resident memory yet.

Error Handling

Process analysis requires robust error handling because the process list changes dynamically:

FileNotFoundError

process_analyzer.py
except FileNotFoundError:
    continue
Why this happens: Processes can terminate between when we list the /proc directory and when we try to read their status file. The process directory disappears, causing a FileNotFoundError. How it’s handled: The function simply continues to the next process. This is expected behavior and not an error condition.
  1. Scanner lists /proc and finds PID 12345
  2. Process 12345 terminates
  3. Scanner tries to open /proc/12345/status
  4. File doesn’t exist → FileNotFoundError
  5. Scanner continues to next process

PermissionError

process_analyzer.py
except PermissionError:
    continue
Why this happens: Some processes (especially system processes) are owned by root or other users. Non-privileged users cannot read their status files. How it’s handled: The function skips processes it cannot access. To analyze all processes, Memory Monitor would need to run with elevated privileges (sudo).
Running Memory Monitor as a regular user will show memory usage for accessible processes. Running with sudo provides complete system-wide visibility.

Silent Failure vs Error Reporting

Both exceptions use continue rather than logging or reporting errors. This design choice:
  • Keeps output clean: Expected conditions don’t clutter results
  • Focuses on success: Reports what it found rather than what it couldn’t access
  • Maintains performance: No overhead from logging frequent, expected conditions

Output Format

The function returns detailed information about the highest memory-consuming process:
process_analyzer.py
return [f"El proceso con mayor VmRSS es \n Name: {max_process_name}\n PID: {max_pid}\n VmRSS: {max_vmrrs} kB", max_pid]
The return value is a list containing:
  1. Formatted string with process name, PID, and VmRSS value
  2. PID alone for programmatic use

Example /proc/[pid]/status Output

Here’s what a typical /proc/[pid]/status file contains:
Name:   firefox
State:  S (sleeping)
Pid:    12345
PPid:   1234
VmSize: 4096000 kB
VmRSS:  2048000 kB
VmData:  512000 kB
...
Memory Monitor extracts:
  • Name: firefox
  • VmRSS: 2048000 (in kB)

Performance Considerations

The current implementation reads line-by-line but could be optimized by reading the entire file and then parsing. However, /proc/[pid]/status files are small (typically < 2KB), so the performance difference is negligible.
The function uses a single-pass algorithm with O(n) time complexity, tracking the maximum as it scans. This is efficient because:
  • Only one pass through the process list is needed
  • No additional memory for sorting
  • Early termination possible if needed
Processes that start after the initial os.listdir("/proc") call won’t be included in this scan. For continuous monitoring, the scan would need to be repeated periodically.

Design Trade-offs

Single Maximum vs Top N

Memory Monitor reports only the single highest memory consumer. To report multiple top processes, you would need to:
  • Use a heap or sorted list structure
  • Store top N processes during iteration
  • Return a list of results

VmRSS vs Other Metrics

The tool could track other memory metrics from /proc/[pid]/status:
  • VmSize: Total virtual memory
  • VmData: Size of data segment
  • VmStk: Size of stack
  • VmExe: Size of executable code
VmRSS was chosen because it represents actual RAM usage, the most actionable metric for system administrators.

Next Steps

Memory Monitoring

Learn how Memory Monitor tracks overall system memory usage

Build docs developers (and LLMs) love