怎么查看Python进程实时内存占用?任务管理器与psutil方法
本文详细解答怎么查看Python进程实时内存占用,涵盖操作系统任务管理器快速定位排查以及使用psutil库进行代码级精准监控的完整实操步骤、核心内存指标(RSS与USS)解析与常见注意事项。
psutil 调用 process.memory_info().rss 或 process.memory_full_info().uss,获取精准到字节级别的物理与独占内存数据。
一、查看 Python 内存前必须理清的核心指标
很多开发者在排查 Python 内存时,常发现不同工具汇报的数值差异很大:系统监控显示占用了几百兆,但 Python 内部排查对象大小却只有几十兆。这是因为操作系统管理的内存与 Python 解释器内部对象所处的层次不同。
操作系统视角下的进程内存由以下几个核心部分构成:
- 物理常驻内存(RSS / Resident Set Size):当前进程在物理 RAM 中真实驻留的内存页大小。任务管理器中常见的“内存 / 工作集”列即对应或包含该项。它包含了与其他进程共享的动态库。
- 独占物理内存(USS / Unique Set Size):该 Python 进程独自占有的物理内存。如果此时关闭该进程,操作系统可以立刻全额回收的物理空间正是 USS。
- 虚拟内存大小(VMS / Virtual Memory Size):进程向系统申请的虚拟地址空间总量,包括实际分配但尚未载入物理内存的页面以及文件映射空间。
- 共享内存(Shared Memory):多个进程共用的只读代码段或系统动态链接库(如 libc、Python 解释器自身的二进制映射)。在 RSS 中通常会包含这部分开销。
二、通过系统任务管理器排查 Python 进程内存
系统自带的任务监视器(Windows 任务管理器、macOS 活动监视器、Linux htop)最大的优势是零侵入性,无论脚本是否在运行,都可以随时打开观察。
1. 前置步骤:确认目标脚本的进程 PID
在开发或生产环境中,后台常常同时运行着多个 Python 实例(如 VS Code 插件后台、系统守护脚本等)。若只看进程名称 python.exe,极易认错对象。最稳妥的方法是在脚本启动时打印当前进程编号:
import os
print(f"当前 Python 进程 PID: {os.getpid()}")
如果脚本已经在后台运行且未打印 PID,可以在终端通过命令辅助查找:
- Windows:运行
wmic process where "name='python.exe'" get ProcessId,CommandLine列出每个 Python 进程对应的命令行参数。 - Linux / macOS:运行
ps aux | grep python,通过命令行的脚本路径定位对应的 PID。
2. 在 Windows 任务管理器中精准读取
- 按下快捷键
Ctrl + Shift + Esc打开任务管理器。 - 点击顶部或左侧的“详细信息(Details)”标签页。注意不要仅停留在“进程”概览页,详细信息页才支持按 PID 排序。
- 在表头任意列右键,点击“选择列(Select columns)”,勾选“PID”、“工作集(内存)”以及“专用工作集(内存)”。
- 点击 PID 列排序列出目标进程。其中,“专用工作集”剔除了跨进程共享的动态库,最能准确反映当前 Python 脚本自身的物理内存消耗。
htop 或 top -p <PID>,重点关注 RES(物理常驻内存)列。
三、使用 psutil 在 Python 代码中实时监控
如果希望在特定业务函数执行前后打点、每隔数秒自动记录内存水位,或者在内存暴涨时触发报警与日志导出,使用跨平台的 psutil 模块是最优解。
1. 安装 psutil
在项目使用的 Python 环境中安装依赖:
pip install psutil
2. 获取当前进程的单次内存快照
psutil.Process() 在不传入参数时默认绑定当前进程。调用 memory_info() 能够返回一个命名元组,单位为字节(Byte):
import os
import psutil
# 绑定当前进程
process = psutil.Process(os.getpid())
# 获取内存信息(字节)
mem_info = process.memory_info()
# 换算为常用单位 MB (MiB)
rss_mb = mem_info.rss / (1024 * 1024)
vms_mb = mem_info.vms / (1024 * 1024)
print(f"进程 PID: {process.pid}")
print(f"常驻物理内存 (RSS): {rss_mb:.2f} MB")
print(f"虚拟内存占用 (VMS): {vms_mb:.2f} MB")
常驻物理内存 (RSS): 42.68 MB
虚拟内存占用 (VMS): 512.44 MB
3. 读取更准确的独占内存(USS)
如果操作系统支持(Windows、Linux 及部分 macOS 环境),可以调用 process.memory_full_info() 获取 uss 属性。USS 剔除了共享库占用,是评估进程真实私有内存的最准确数值:
try:
full_info = process.memory_full_info()
uss_mb = full_info.uss / (1024 * 1024)
print(f"独占物理内存 (USS): {uss_mb:.2f} MB")
except (psutil.AccessDenied, AttributeError):
print("当前平台或权限不支持获取 USS,建议以 RSS 为准")
4. 搭建定时轮询的实时监控函数
在长时间运行的爬虫、批处理脚本或模型推理任务中,可以通过定时循环采样来观测内存趋势。以下是一个轻量、开箱即用的实时采样函数:
import time
import os
import psutil
def track_memory(interval_sec=1.0, count=5):
"""
按指定间隔采样并输出当前 Python 进程的物理与独占内存
:param interval_sec: 采样间隔(秒)
:param count: 采样次数
"""
process = psutil.Process(os.getpid())
print(f"开始监控进程 [PID: {process.pid}], 采样间隔: {interval_sec}s")
print("-" * 52)
print(f"{'采样时间':<12} | {'常驻内存 (RSS)':<16} | {'独占内存 (USS)':<16}")
print("-" * 52)
for _ in range(count):
# 兼容性读取
mem = process.memory_info()
rss = mem.rss / (1024 * 1024)
try:
uss = process.memory_full_info().uss / (1024 * 1024)
uss_str = f"{uss:8.2f} MB"
except (AttributeError, psutil.AccessDenied):
uss_str = " N/A"
now_str = time.strftime("%H:%M:%S")
print(f"{now_str:<12} | {rss:8.2f} MB | {uss_str}")
time.sleep(interval_sec)
if __name__ == "__main__":
# 模拟业务运行期间的内存监测
track_memory(interval_sec=1.5, count=4)
----------------------------------------------------
采样时间 | 常驻内存 (RSS) | 独占内存 (USS)
----------------------------------------------------
14:20:01 | 42.68 MB | 36.15 MB
14:20:02 | 68.90 MB | 61.32 MB
14:20:04 | 124.50 MB | 116.88 MB
14:20:05 | 124.52 MB | 116.90 MB
四、为什么 del 变量后任务管理器中的内存没有立即下降?
这是在监控 Python 内存时最常见到的疑问:在代码中调用了 del large_list 甚至显式调用了 gc.collect(),但在任务管理器或 psutil 中查看,RSS 并没有明显回落。
背后的核心机制是 Python 的内存管理体系(pymalloc 内存池):
- 对象池机制:对于小于 512 字节的小对象(如普通数字、字符串、小元组等),Python 会在底层向系统申请 256KB 大小的内存池(Arena)。对象被销毁后,这部分内存会由 Python 内部空闲列表接管留作后续创建新对象使用,而不会立即把物理页退还给操作系统内核。
- 只有全空整块才还给系统:只有当一整个 Arena 内的所有内存池块全部被清空时,Python 才会调用操作系统的 free 接口将内存页归还给系统。
- 排查建议:判断程序是否存在内存泄漏,不应看某一次
del是否立竿见影回落,而应看多轮任务循环迭代后,整体内存基线是否稳定,或者是否呈现无上限的持续阶梯式攀升。
五、任务管理器与 psutil 方案对比与选择建议
针对不同的排查场景,两种方式各自具备明确的分工:
| 对比维度 | 系统任务管理器 / 监视器 | psutil 库方法 |
|---|---|---|
| 调用方式 | 操作系统图形界面 / 终端内置命令 | Python 代码调用 API 接口 |
| 代码侵入 | 完全零代码侵入 | 需要安装第三方库并在程序中引用 |
| 监控指标 | 以工作集(RSS)、专用工作集为主 | 包含 RSS、VMS、USS 等,精度到字节 |
| 可自动化度 | 人工目测,难以做长周期量化记录 | 完全可编程,支持定时落地日志与异常熔断 |
| 多进程支持 | 需在列表多行分别查找各子进程 | 支持 process.children() 自动递归汇总 |
- 生产应急排查:脚本已在远端或本地卡死时,首选通过 PID 打开任务管理器或
htop,快速判断是否已把整机物理内存打满导致系统进入 Swap 交换。 - 常规开发与性能测试:在重要数据处理批次前后使用
psutil打点,结合 USS 指标评估代码段的内存净增量,以便在持续集成环境中及早发现内存泄漏隐患。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













