Python 内存占用持续增长的治理方案
发布时间 - 2026-01-28 00:00:00 点击率:次gc.collect() 有时无效是因为对象未被识别为可回收,如含__del__的循环引用或被全局容器持有;应使用tracemalloc定位内存大户,用gc.get_referrers()追踪强引用链。
为什么 gc.collect() 有时完全没用
调用 gc.collect() 后内存不降,往往不是垃圾回收器失灵,而是对象根本没被识别为“可回收”——比如循环引用中混入了自定义 __del__ 方法,或对象被全局容器(如模块级 list、dict)意外持有。Python 的引用计数机制会优先处理无循环的引用,而 gc 模块只负责检测循环引用,且默认不扫描含 __del__ 的对象。
实操建议:
- 先用
gc.set_debug(gc.DEBUG_STATS)开启统计,观察是否真有未回收对象; - 检查是否有类似
cache = []这样的模块级变量在持续append(); - 避免在类中定义
__del__,改用weakref.finalize替代; - 对疑似泄漏对象,用
sys.getrefcount(obj)或gc.get_referrers(obj)追踪谁在持有着它。
如何定位真正吃内存的 Python 对象
靠 psutil.Process().memory_info().rss 只能看到进程总内存,无法定位到具体对象。必须下钻到 Python 对象层级。
实操建议:
- 用
tracemalloc模块(Python 3.4+ 内置):启动时调用tracemalloc.start(),之后用tracemalloc.get_top_stats(10)查看分配最多内存的代码行; - 注意
tracemalloc默认只记录前 256 帧,大项目需提前设tracemalloc.start(25) # 25MiB 跟踪上限; - 若怀疑是 NumPy/Pandas 导致,直接检查
.nbytes或.memory_usage(deep=True).sum(),它们常因视图(view)复用底层 buffer 而不释放; - 警惕
logging模块:如果 handler 持有大量日志 record(尤其用MemoryHandler),也会拖慢回收。
del 和 None 赋值的区别在哪
del obj 删除的是名字绑定,不是对象本身;obj = None 是重新绑定,原对象只要还有其他引用就依然存活。两者都不保证立即释放内存,只是移除一个引用路径。
实操建议:
- 对大型临时对象(如读取的大文件内容、DataFrame 中间结果),优先用
del obj+ 显式gc.collect()(仅限关键路径,别滥用); - 在函数内创建的大对象,通常无需手动干预——函数返回后局部变量自动解绑,引用计数归零即释放;
- 若对象被闭包、lambda 或弱引用容器持有,
del无效,得查清持有者再清理; - 切勿在循环里频繁调用
gc.collect(),它会暂停所有线程,反而拖慢吞吐。
第三方库引发的隐性内存滞留
像 requests、sqlalchemy、torch 这类库常自带连接池、缓存或上下文管理逻辑,表面看没泄漏,实则内部对象长期驻留。例如 requests.Session() 默认启用连接池,pool_connections=10 意味着最多保持 10 个空闲连接对象;SQLAlchemy 的 Query 对象若未显式关闭,其结果集可能延迟释放。
实操建议:
- 用
requests.Session()时,确保在合适时机调用session.close(),或用with session as s:上下文; - SQLAlchemy 中,避免长时间持有
session.query(...).all()返回的全量 list,改用yield_per()流式处理; - PyTorch 训练中,记得在每个 batch 后调用
loss.detach()和del loss,,否则计算图节点持续累积;
outputs
- 所有带缓存的库(如
functools.lru_cache),检查maxsize是否设为None——这等于无限缓存,极易失控。
内存增长问题最难的不是发现,而是确认“谁还在强引用那个本该消失的对象”。越早用 tracemalloc 或 gc.get_referrers() 锁定根引用链,越能避开靠猜和重启掩盖问题的习惯。
# python
# app
# session
# pytorch
# 区别
# 内存占用
# 垃圾回收器
# 为什么
# batch
# numpy
# pandas
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
深圳网站制作培训,深圳哪些招聘网站比较好?
网页设计与网站制作内容,怎样注册网站?
佛山网站制作系统,佛山企业变更地址网上办理步骤?
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工
Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】
Laravel如何创建自定义中间件?(Middleware代码示例)
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
利用JavaScript实现拖拽改变元素大小
如何快速完成中国万网建站详细流程?
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
Python文件操作最佳实践_稳定性说明【指导】
浅谈Javascript中的Label语句
如何在腾讯云服务器上快速搭建个人网站?
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出
高端云建站费用究竟需要多少预算?
企业网站制作这些问题要关注
香港服务器建站指南:免备案优势与SEO优化技巧全解析
Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】
JavaScript中如何操作剪贴板_ClipboardAPI怎么用
WordPress 子目录安装中正确处理脚本路径的完整指南
js实现获取鼠标当前的位置
Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧
Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】
如何为不同团队 ID 动态生成多个独立按钮
免费网站制作appp,免费制作app哪个平台好?
Laravel如何发送系统通知?(Notification渠道示例)
Laravel如何自定义错误页面(404, 500)?(代码示例)
详解Oracle修改字段类型方法总结
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】
PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑
Java类加载基本过程详细介绍
javascript基于原型链的继承及call和apply函数用法分析
SQL查询语句优化的实用方法总结
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
Linux后台任务运行方法_nohup与&使用技巧【技巧】
如何在阿里云虚拟服务器快速搭建网站?
Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理
Laravel怎么在Controller之外的地方验证数据
高防服务器租用如何选择配置与防御等级?
如何在宝塔面板创建新站点?
网站制作报价单模板图片,小松挖机官方网站报价?
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
如何在IIS7上新建站点并设置安全权限?
javascript中闭包概念与用法深入理解
如何快速生成专业多端适配建站电话?


