核心要点

  • 知道 CPython 小整数/短字符串等对象池与引用计数

  • 理解循环引用与 gc 模块的分代回收

  • 能对比 Python GC 与 JVM/手动管理的差异

标准回答

内存分配:CPython 在堆上为对象分配内存,有 pymalloc 小对象分配器(<512 字节)减少系统调用开销。

引用计数(主要机制):每个对象有 ob_refcnt,引用 +1、失效 -1,归零立即释放。优点:确定性、低延迟;缺点:无法自动处理循环引用

循环垃圾回收gc 模块对容器对象做分代回收(0/1/2 代),检测并打破引用环。可用 gc.disable() 关闭(极少场景)。

intern 与池化:小整数 [-5, 256]、部分短字符串被 intern,节省内存。

与 AI 工程:大 NumPy 数组/PyTorch Tensor 多在 C 扩展层管理,不受纯 Python GC 同等影响;注意 GPU 显存del + torch.cuda.empty_cache() 等显式管理。

常见误区

⚠️ 常见踩坑

误以为 del x 或引用计数归零就把内存还给了操作系统——CPython 的 pymalloc 常把小块内存留在内部池里复用。还有人以为引用计数能处理一切,忽略了循环引用必须靠分代 gc 才能回收;含 del 的对象一旦陷入循环引用,旧版 Python 还可能回收失败。

追问

追问 1什么是循环引用?举例说明。

a = []; b = [a]; a.append(b) 形成 list 互相引用,引用计数永不为零。可用 gc.collect() 检测回收;设计时用 weakref 打破环,或显式 del 断开引用。

追问 2del x 会立即释放内存吗?

del x 只删除当前作用域的名字绑定,引用计数减一;计数归零时对象析构,但 pymalloc 可能缓存小块内存供后续复用,不一定立刻归还操作系统。大对象或 mmap 分配的更可能及时释放给 OS。

追问 3PyPy 的 GC 和 CPython 有何不同?

PyPy 用增量式 GC(非引用计数为主),停顿更可控,适合长驻服务;CPython 引用计数在每次引用变化时有开销但释放及时。二者对扩展 C 库的行为可能不同。

延伸学习

与本题相关的知识库文章、术语、工具与行业资讯。