Python 内存泄漏排查面试复盘

1. 这轮我掌握的核心结论

  • 面试里这题的关键是排查思路,不是背工具参数。
  • 标准流程:
    1. 先确认现象(RSS 是否持续上涨、是否可稳定复现)
    2. 再定位热点(tracemalloc 前后快照 + compare_to)
    3. 再查引用链(gc / objgraph)
    4. 修复后回归验证(同样压测下内存是否趋稳)
  • 如果 RSS 在涨,但 tracemalloc 看不出热点,要考虑 C 扩展层分配,使用 memray(常在 Linux/WSL 使用)。

2. 本次实操案例(可作为面试回答素材)

案例:全局容器导致内存持续增长

  • 泄漏版文件:code/memory_leak_lab/case1_global_list.py
  • 现象:每次调用都构造约 200KB payload 并 append 到全局 LEAK_BUCKET,导致对象一直被引用。
  • 使用 tracemalloc 分析后,增长热点定位到 payload 构造和 append 对应代码行。

修复方案

  • 修复版文件:code/memory_leak_lab/case1_fixed_bounded.py
  • 改法:把无界 list 改为有界 deque(maxlen=100)。
  • 结果:
    • 修复前:对象数量和内存随迭代线性增长
    • 修复后:count 稳定在 100 左右,内存趋于稳定

这个"修复前后对比"是很好的面试证据链。


3. 关键概念速记

RSS 是什么

  • RSS(Resident Set Size)= 进程当前驻留在物理内存中的大小。
  • Windows 下常看 WorkingSet / WorkingSet64(可近似 RSS)。

compare_to(..., "lineno") 里的 lineno

  • lineno = line number(代码行号)
  • 表示按"文件 + 行号"聚合内存增长,适合快速定位。

compare_to 常见 key_type

  • filename:按文件聚合(粗粒度)
  • lineno:按行聚合(常用)
  • traceback:按完整调用栈聚合(细粒度)

4. objgraph.show_growth() 输出怎么看

输出列含义:

  • 第 1 列:对象类型名(如 dict、list、function)
  • 第 2 列:当前该类型对象总数
  • 第 3 列:相对上次 show_growth() 的增量(+N)

注意:第一次调用常包含初始化噪音。实践里应该:

  1. gc.collect()
  2. 先 show_growth() 建基线
  3. 跑业务循环
  4. 再 gc.collect() + show_growth(limit=10) 看真实增量

5. 面试可直接说的回答模板

我会先确认问题是否可复现,并观察 RSS 是否持续上涨;然后用 tracemalloc 在执行前后拍快照,通过 compare_to 定位增长最明显的代码行;如果对象没有释放,再用 gc/objgraph 查引用链,找出根引用(比如全局容器或无界缓存);修复后用同样压测回归,确认内存从线性增长变为稳定。若 RSS 增长与 tracemalloc 不匹配,我会怀疑 C 扩展层,并用 memray 进一步分析。


6. 我的真实表达策略(避免"硬编经历")

如果被问"你解决过吗",可以诚实表达:

  • 线上未必遇到过典型事故,但做过完整演练
  • 能给出复现、定位、修复、回归的完整闭环
  • 有实际脚本和结果支撑,不是只会背概念

这样既真实,也能体现工程能力。

相关推荐
晨米酱4 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
彧azz4 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
CoderYanger5 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法
爱学习的执念5 天前
助力金九银十1000道软件测试面试题(功能、接口、自动化、WEB、APP.......)附答案
软件测试·面试
小的~~5 天前
银河麒麟V10 ARM部署TDengine(涛思)工业时序数据库安装与测试
面试·程序员创富
2401_832298105 天前
人机协同:AI时代全新工作与学习范式
职场和发展
童园管理札记5 天前
从政策驱动到课堂落地:2026年“人工智能+教育”全景解读与技术实践指南
人工智能·python·深度学习·职场和发展·学习方法
小刘在重生~5 天前
Oracle_day2 单行函数|组函数|分组|伪列|子查询|分页|多表连接
笔记·oracle·面试
Sam_Deep_Thinking5 天前
关于java final关键字的可见性
java·后端·面试·程序员
yuanxi2005 天前
卡塔尔能源公司LNG扩建项目首条生产线预计明年投运:大客户销售的5个判断
职场和发展·创业创新·学习方法