You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动