新闻详情

新闻详情

首页 / 资讯中心 / 详情

一次内存泄漏排查,让我彻底懂了Python引用

发布时间:2026/9/28 3:42:58来源:尧图网络
一次内存泄漏排查,让我彻底懂了Python引用
那是一个再普通不过的周五下午监控突然报警服务内存持续上涨已经逼近容器上限。我第一反应是“又有人写死循环了”但日志一切正常QPS平稳接口响应也没变慢。唯独内存像漏水的桶只涨不跌。重启服务内存回落。可跑了两小时又涨回去了。这不是偶发是必然。排查从tracemalloc到objgraph我先用tracemalloc抓快照对比两个时间点的内存分配。结果指向一个全局字典_cache它的大小在持续增长。这个字典是我半年前写的“本地缓存”用来存用户会话对象。python复制下载_cache {} def get_user(user_id): if user_id not in _cache: _cache[user_id] User(user_id) return _cache[user_id]问题很明显只增不减。但奇怪的是我明明设置了过期时间后台线程每10分钟清理一次。为什么没生效我打开清理逻辑python复制下载def clean_cache(): now time.time() for uid, user in _cache.items(): if now user.last_active 600: del _cache[uid]逻辑没错。但为什么user.last_active一直没更新我翻到User类python复制下载class User: def __init__(self, uid): self.uid uid self.last_active time.time() self.session Session(self) # 关键User持有一个Session而Session又反过来持有Userpython复制下载class Session: def __init__(self, user): self.user user循环引用但这还不是最致命的。真正的问题是Session在别处被另一个全局列表_active_sessions引用了而那个列表从未清理。于是User被Session引用Session被全局列表引用整个对象链永远无法回收。del _cache[uid]只是删掉了字典里的引用但_active_sessions里的引用还在引用计数不为零GC也不会回收因为它们是可达的。解决弱引用与显式清理我做了两件事。第一把_active_sessions改成weakref.WeakSetpython复制下载import weakref _active_sessions weakref.WeakSet()这样Session被弱引用当_cache中删除User后User不再被强引用Session也随之被回收。第二在clean_cache里显式断开循环python复制下载user.session.user None del _cache[uid]双管齐下内存曲线终于平了。彻悟Python引用的三层真相这次排查让我彻底理解了Python引用机制。第一层引用计数是主力。每个对象记录被引用次数归零即回收。del只是删除一个引用不是删除对象。如果还有其他引用对象依然存活。第二层循环引用需要GC。引用计数无法处理互相引用的对象。Python的垃圾回收器会定期扫描标记并清除不可达的循环。但GC不是实时的也不是万能的。如果循环对象被全局变量引用它们始终“可达”GC也救不了。第三层弱引用是解药。weakref不增加引用计数让对象可以被回收。缓存、观察者模式、父子引用中弱引用能有效避免内存泄漏。以前我总觉得“Python自动管理内存不用操心”。现在才明白自动管理的前提是你得理解它的规则。引用在哪里对象就在哪里。引用不断内存不还。那次之后我养成了习惯写全局缓存必用弱引用写循环引用必显式断开上线前必用objgraph看一眼对象增长。内存泄漏不可怕可怕的是不懂引用还怪Python。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

RL-赵-(二)-基于模型:贝尔曼/Bellman公式04-1【贝尔曼方程的矩阵-向量形式(Matrix-Vector Form)】【v_π=r_π+γP_π·v_π】 2026/9/28 4:37:03

RL-赵-(二)-基于模型:贝尔曼/Bellman公式04-1【贝尔曼方程的矩阵-向量形式(Matrix-Vector Form)】【v_π=r_π+γP_π·v_π】

RL-赵-(二)-基于模型:贝尔曼/Bellman公式04【贝尔曼方程的矩阵-向量形式(Matrix-Vector Form)】【从Bellman方程求解State Value:①闭式解、②迭代解】 2.6 贝尔曼方程的矩阵-向量形式(Matrix-Vector Form of the Bellman Equation) vπ(s)=E[Rt+1∣St=s]+γE[Gt+1∣S…

阅读更多 →
小龙虾OpenClaw 2026/9/28 4:37:03

小龙虾OpenClaw

主要含义:OpenClaw 的网友昵称- 为什么叫小龙虾:OpenClaw 的图标是一只红色卡通龙虾("Claw"就是虾钳),网友顺口就叫它"小龙虾""AI 龙虾"。- "养龙虾"是什么:因为它…

阅读更多 →
一名员工从招聘、入职、试用、合同、考勤走到转岗离职,OA 的价值就藏在这些连续动作里 2026/9/28 4:37:02

一名员工从招聘、入职、试用、合同、考勤走到转岗离职,OA 的价值就藏在这些连续动作里

制造企业招进一名员工,表面上只是花名册里多了一行。真正发生的事情却远不止这些。用人部门提出招聘需求,人事收集简历、安排面试、确认录用。员工报到以后,要建立档案、签订合同、进入试用期。部门负责人要完成试用评价和转正审批&#xff0…

阅读更多 →
长沙网站制作首页图解步骤:零基础避坑指南 2026/9/28 4:37:02

长沙网站制作首页图解步骤:零基础避坑指南

长沙网站制作首页图解步骤:零基础避坑指南 想做个官网展示公司实力,结果打开浏览器对着空白文档发呆,连 <div> 和 <body>…

阅读更多 →
杂记08 CSRF 跨站请求伪造 2026/9/28 4:37:02

杂记08 CSRF 跨站请求伪造

CSRF 的本质只有一句话&#xff1a;我让你&#xff08;已登录用户&#xff09;的浏览器&#xff0c;替我发一个请求。 本文按「原理 → GET/POST 两种类型 → 三个递进靶场 → XSS 对比 → 防御」组织&#xff0c;靶场难度从 1 级递进到高阶。⚠️ 本文所有测试均在授权靶场中完…

阅读更多 →
STM32驱动W25Q64 Flash的SPI配置避坑指南 2026/9/28 4:36:55

STM32驱动W25Q64 Flash的SPI配置避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉