Python 怎么监控内存使用并在泄漏时自动报警?
技术百科
冷炫風刃
发布时间:2026-01-23
浏览: 次 用psutil.Process(os.getpid()).memory_info().rss可准确获取Python进程真实内存占用(RSS),避免sys.getsizeof()等仅统计Python对象的局限;需每1–5秒采样,结合斜率与GC回落判断泄漏,多进程须独立监控,C扩展内存需依赖RSS趋势识别。
怎么用 psutil 实时查 Python 进程内存占用
直接靠 sys.getsizeof() 或 gc.get_objects() 无法反映真实内存压力,它们只统计 Python 对象堆内大小,不包含 C 扩展、mmap、共享库等。真正可靠的是从操作系统层面读进程 RSS(Resident Set Size)。
用 psutil 是最轻量且跨平台的选择:
import psutil import osp = psutil.Process(os.getpid()) rss_mb = p.memory_info().rss / 1024 / 1024 # 转 MB print(f"当前 RSS: {rss_mb:.1f} MB")
- 务必用
p.memory_info().rss,不是vms(虚拟内存不可靠) - Linux 下 RSS 基本等于“实际占物理内存”,Windows/macOS 行为略有差异但足够用于趋势判断
- 不要在循环里频繁调用——
psutil.Process()初始化有开销,建议每 1–5 秒采样一次
怎么定义“内存泄漏”并触发报警
内存泄漏不是“内存一直涨”,而是“持续增长且不回落”。单纯设阈值(如 >500MB)容易误报,比如临时大文件处理。
更稳妥的方式是监控**增长斜率 + 回落失败**:
- 记录最近 N 次 RSS 值(例如 10 次,间隔 3 秒)
- 用线性拟合或简单差分判断是否连续 5 次上涨,且涨幅 >5MB/次
- 同时检查 GC 是否有效:调用
gc.collect()后 RSS 下降 - 报警前再 sleep 1 秒重采一次,排除瞬时毛刺
示例逻辑片段:
import gc
# ... rss_history 维护一个 deque(maxlen=10)
if len(rss_history) == 10 and all(rss_history[i] < rss_history[i+1] for i in range(5, 9)):
gc.collect()
time.sleep(1)
rss_after_gc = p.memory_info().rss / 1024 / 1024
if rss_after_gc > rss_history[-1] * 0.99: # 未回落超 1%
trigger_alert(rss_after_gc)
报警该怎么做才不被忽略
发个 print() 或写日志基本等于没报。真要起作用,得打通运维链路:
- 写入本地告警文件(如
/tmp/memory_alert.pid),配合 systemd 的PathExists监控自动拉起处理脚本 - 调用企业微信/钉钉 Webhook(注意加签名和限频,避免刷屏)
- 向 Prometheus Pushgateway 推送指标(
memory_leak_detected{pid="12345"} 1),再由 Alertmanager 发通知 - 切忌用
smtplib自建邮件——SMTP 很容易被当垃圾邮件拦截,且无送达反馈
为什么多线程/多进程下容易误判
psutil.Process(os.getpid()) 在

multiprocessing,每个子进程需独立监控——父进程无法直接看到子进程 RSS。
- 子进程启动时,手动传入监控开关和告警通道(如 queue 或 pipe)
- 避免用
fork后的进程继承父进程监控逻辑,因为 fork 时 RSS 会虚高(写时复制未触发) - 若用
concurrent.futures.ProcessPoolExecutor,建议改用ThreadPoolExecutor配合对象池复用,从源头减少进程级内存震荡
最常被忽略的一点:C 扩展(如 numpy、pandas、cv2)分配的内存不经过 Python GC,RSS 上涨但 gc.get_count() 完全不动——这类泄漏只能靠 RSS 趋势发现,无法靠对象计数定位。
# 操作系统
# 这类
# 微信
# 怎么做
# python
# windows
# 是从
# 不被
# 很容易
# mac
# win
# linux
# 循环
# 对象
# macos
# 堆
# 内存占用
# 钉钉
# 虚拟内存
# 企业微信
# 你用
# 拉起
# 不动
# 真要
# 通运
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- c++怎么调用nana库开发GUI_c++ 现代风
- Win11怎么打开旧版计算器_Win11恢复传统计
- Windows10如何更改鼠标灵敏度_Win10鼠
- php8.4如何调用com组件_php8.4win
- Python高性能计算项目教程_NumPyCyth
- 如何在Golang中引入测试模块_Golang测试
- 如何在Golang中使用encoding/gob序
- Python安全爬虫设计_IP代理池与验证码识别策
- Win11怎么关闭应用权限_Windows11相机
- Win11时间格式怎么改成12小时制 Win11时
- Win11麦克风没声音怎么设置_Win11麦克风权
- 如何使用Golang匿名函数_快速定义临时函数逻辑
- Win10路由器怎么隐藏ssid Win10隐藏w
- Win10系统怎么查看端口状态_Windows10
- c++中如何求一个数的平方根_c++ sqrt函数
- Win11蓝牙开关不见了怎么办_Win11蓝牙驱动
- Win10怎样卸载自带Edge_Win10卸载Ed
- c++ atoi和atof函数用法_c++字符数组
- 本地php环境出现502错误_nginx或apac
- Win11怎么关闭定位服务_保护Win11位置隐私
- 如何使用Golang进行HTTP服务性能测试_测量
- Python代码测试策略_质量保障解析【教程】
- Windows10电脑怎么设置电源按钮_Win10
- MySQL 中使用 IF 和 CASE 实现查询字
- Win11怎样安装钉钉客户端_Win11安装钉钉教
- Python生成器表达式内存优化_惰性计算说明【指
- c++怎么实现大文件的分块读写_c++ 文件指针s
- WindowsUSB驱动安装异常怎么办_USB驱动
- Win10如何卸载自带Edge_Win10彻底卸载
- Python多进程教程_multiprocessi
- php中self::能调用子类重写的方法吗_静态绑
- C#如何使用Channel C#通道实现异步通信
- Windows服务无法启动错误1067是什么_进程
- php串口通信波特率怎么选_根据硬件手册设置正确波
- 如何高效删除 NumPy 二维数组中所有元素相同的
- Windows7如何安装系统镜像_Windows7
- 短链接还原php提示内存不足_调整PHP内存限制设
- php做exe支持多线程吗_并发处理实现方式【详解
- Win11时间不对怎么同步_Win11自动校准互联
- Win11怎么设置快速访问_Windows11文件
- Windows10如何查看保存的WiFi密码_Wi
- c# 服务器GC和工作站GC的区别和设置
- Mac如何设置动态壁纸?(让桌面动起来)
- Win11怎么关闭触控板_Win11笔记本禁用触摸
- 如何在同包不同文件中正确引用 Go 结构体
- C++如何将C风格字符串(char*)转换为std
- c++如何判断文件是否存在_c++ filesys
- 如何使用Golang table-driven f
- php8.4xdebug无法调试怎么办_php8.
- Win11如何设置计划任务 Win11定时执行程序

QQ客服