Linux环境下如何用Python统计进程及其所有子进程的联合内存占用
Linux环境下如何用Python统计进程及其所有子进程的联合内存占用
这确实是个很实际的问题——直接累加各个进程的rss(Resident Set Size)会因为共享内存(比如系统库、进程间共享段)被重复计算,导致结果比实际物理内存占用虚高很多。好在我们可以通过psutil库结合**PSS(Proportional Set Size)**来解决这个问题,这是Linux上专门针对共享内存场景设计的更准确的内存统计指标。
核心思路:用PSS替代RSS计算
PSS的核心优势是会把共享内存按使用该内存的进程数量平均分摊。比如一个100MB的共享库被5个进程共用,每个进程的PSS里只会计入20MB的该库内存,累加所有进程的PSS后,这部分共享内存只会被统计为100MB,完全匹配实际的物理内存占用情况。
具体实现代码
下面是一个基于psutil的完整函数,能计算指定PID及其所有子孙进程的总PSS内存占用:
import psutil def calculate_total_process_tree_memory(pid): try: # 初始化父进程对象 parent_proc = psutil.Process(pid) # 获取进程树的所有进程(包括父进程自己) all_procs = [parent_proc] + parent_proc.children(recursive=True) total_pss = 0 for proc in all_procs: try: # 获取包含PSS的完整内存信息 full_mem_info = proc.memory_full_info() total_pss += full_mem_info.pss except psutil.NoSuchProcess: # 处理遍历过程中进程已退出的情况 print(f"警告:进程 {proc.pid} 已不存在,跳过统计") except psutil.AccessDenied: # 处理无权限访问进程信息的情况 print(f"警告:无权限访问进程 {proc.pid} 的内存信息,跳过统计") # 转换为MB单位,方便阅读 total_pss_mb = total_pss / (1024 * 1024) return round(total_pss_mb, 2) except psutil.NoSuchProcess: return f"错误:指定的进程 {pid} 不存在" # 用法示例:替换为你需要监控的进程PID target_pid = 1234 result = calculate_total_process_tree_memory(target_pid) if isinstance(result, float): print(f"进程树(PID {target_pid})的总内存占用(PSS):{result} MB") else: print(result)
补充说明
- 为什么不直接用RSS?
rss统计的是进程占用的所有物理内存,包含完全共享的部分,直接累加会导致共享内存被多次计算,结果严重失真。 memory_full_info()是psutil中用于获取详细内存指标的方法,除了PSS,还包含uss(Unique Set Size,进程完全独占的内存,不包含任何共享部分)、swap等指标,你可以根据需求灵活调整。- 如果需要更底层的实现,也可以直接解析Linux系统的
/proc/[pid]/smaps文件(每个进程的内存映射详情),但psutil已经封装了这些逻辑,用起来更省心且不易出错。
备注:内容来源于stack exchange,提问作者MWB




