From a5d226503d9bf1edd6cbdf8e73b43967f70307d4 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Sun, 22 Feb 2026 23:53:10 +0100 Subject: [PATCH] feat: implement PSS (Proportional Set Size) for accurate real memory tracking --- src-tauri/src/main.rs | 29 +++++++++++++++++++++++++++-- src/App.tsx | 4 ++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 9e9d7e1..908a8f5 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -10,6 +10,29 @@ use tauri::State; use serde::{Serialize, Deserialize}; use std::collections::HashMap; use chrono::{DateTime, Utc}; +use std::fs; + +// --- Helper for Real Memory (PSS) on Linux --- + +fn get_pss(pid: u32) -> Option { + // PSS (Proportional Set Size) is the most accurate "real" memory metric. + // It counts private memory + proportional share of shared libraries. + // smaps_rollup is a fast way to get this on modern Linux kernels. + let path = format!("/proc/{}/smaps_rollup", pid); + if let Ok(contents) = fs::read_to_string(path) { + for line in contents.lines() { + if line.starts_with("Pss:") { + let parts: Vec<&str> = line.split_whitespace().collect(); + if parts.len() >= 2 { + if let Ok(kb) = parts[1].parse::() { + return Some(kb * 1024); + } + } + } + } + } + None +} // --- Data Structures --- @@ -139,12 +162,13 @@ fn get_system_stats( sys.processes().iter() .map(|(pid, process)| { let pid_u32 = pid.as_u32(); + let memory = get_pss(pid_u32).unwrap_or_else(|| process.memory()); ProcessStats { pid: pid_u32, parent_pid: process.parent().map(|p| p.as_u32()), name: process.name().to_string_lossy().to_string(), cpu_usage: process.cpu_usage(), - memory: process.memory(), + memory, status: format!("{:?}", process.status()), user_id: process.user_id().map(|uid| uid.to_string()), is_syspulse: is_descendant_of(pid_u32, self_pid, &sys), @@ -159,12 +183,13 @@ fn get_system_stats( processes = sys.processes().iter() .map(|(pid, process)| { let pid_u32 = pid.as_u32(); + let memory = get_pss(pid_u32).unwrap_or_else(|| process.memory()); ProcessStats { pid: pid_u32, parent_pid: process.parent().map(|p| p.as_u32()), name: process.name().to_string_lossy().to_string(), cpu_usage: process.cpu_usage(), - memory: process.memory(), + memory, status: format!("{:?}", process.status()), user_id: process.user_id().map(|uid| uid.to_string()), is_syspulse: is_descendant_of(pid_u32, self_pid, &sys), diff --git a/src/App.tsx b/src/App.tsx index 0293d43..fb266d0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -580,8 +580,8 @@ function ReportView({ report, onBack }: { report: ProfilingReport, onBack: () =>
- - Memory is Resident Set Size (RSS). Summed totals may exceed physical RAM due to shared segments. + + Memory is Proportional Set Size (PSS). It includes private memory plus a proportional share of shared libraries, providing an accurate sum of total system impact.