人人都会AI编程

分代回收:新生代、中生代、老年代优化策略

更新时间:2026-07-12

垃圾回收(GC)需要遍历所有对象来判断哪些该回收,如果每次都对全部对象做一次全量扫描,开销会很大。Python 采用分代回收策略来优化这个过程,它基于一个很朴素的假设:大多数对象存活时间很短,年纪越大的对象越不容易变成垃圾。

基于这个假设,Python 把对象划分成三个“代”,每个代采用不同的回收频率和策略。

三代划分

  • 第 0 代(新生代):刚创建的对象都先放在这里。它们的生命周期往往很短,比如循环里的临时变量、函数调用结束后的局部变量,很快就会被回收。这一代的对象数量增长最快,所以回收频率最高
  • 第 1 代(中生代):经过一次第 0 代回收后仍然存活的对象会晋升到第 1 代。它们已经证明自己能活过一轮 GC,可能会继续存在一段时间。
  • 第 2 代(老年代):在多次回收中一直存活的对象最终会进入第 2 代。这些通常是模块级别的变量、全局缓存、单例对象等,生命周期几乎与程序运行时间相同。老年代回收频率最低,因为很多对象就是需要长期存在的。

回收触发机制
Python 的分代回收由阈值(threshold)控制。每代都有一个计数器,记录分配的对象数量减去释放的数量。当这个计数器超过对应阈值时,就会触发一次当前代及所有更年轻代的垃圾回收。

  • 默认阈值是 (700, 10, 10),即第 0 代计数器达到 700 时触发回收,第 1 代和第 2 代则是在上一代回收次数达到 10 次时才触发。
  • 这样设计的好处是:最年轻的对象被频繁检查,年老对象很少被打扰,减少了不必要的扫描开销。

回收过程
以第 0 代为例:回收时,会找出当前代中所有“可达”对象(从根引用出发能访问到的),不可达对象则被释放;存活的对象会提升到第 1 代。这种晋升机制避免了反复扫描长期对象,提高了效率。

实际开发中的意义

  • 无需干预:在绝大多数场景下,分代回收是全自动的,开发者不需要手动调整参数。对业务代码的影响是,短命的临时变量会被快速回收,不会堆积。
  • 调优窗口:如果程序确实存在大量短期对象疯狂创建、或者长期对象频繁被错误回收的情况,可以通过 gc.set_threshold() 修改阈值,或者通过 gc.disable() 临时关闭自动 GC 手动控制,但这只在极少数高性能需求下有需要。
  • 调试帮助gc.get_stats() 可以查看各代的回收统计信息,帮助定位内存问题。

分代回收与引用计数、标记-清除一起构成了 Python 完整的内存管理方案。它让 Python 在保持“自动内存管理”便利性的同时,有效控制了垃圾回收的性能开销。