Python 内存管理基础:引用计数与垃圾回收
文章目录前言一、先搞懂Python 里的对象到底是什么二、引用计数Python 内存管理的基石2.1 引用计数是什么2.2 哪些行为会改变引用计数2.3 如何手动查看引用计数2.4 引用计数的优点与缺点三、循环引用引用计数的死穴3.1 什么是循环引用3.2 循环引用在实际代码中多吗四、Python 垃圾回收GC专门干掉循环引用4.1 标记-清除算法原理4.2 分代回收核心思想「活越久越不是垃圾」4.3 2026年Python默认GC阈值真实可查4.4 手动控制GC五、Python 3.12 内存优化新特性2026年最新5.1 更快的分配器obmalloc 优化5.2 引用计数操作原子化多核安全5.3 GC 暂停时间进一步降低5.4 对“短命临时对象”更友好六、实战写出更省内存的Python代码6.1 避免不必要的对象创建6.2 及时删除大对象6.3 避免隐性循环引用6.4 使用弱引用 weakref6.5 生产环境建议七、常见面试题总结2026年依然高频八、总结P.S. 无意间发现了一个巨牛的人工智能教程非常通俗易懂对AI感兴趣的朋友强烈推荐去看看[传送门https://blog.csdn.net/HHX_01](https://blog.csdn.net/HHX_01/article/details/159613021)前言很多刚入门Python的同学写代码时只关心「功能能不能跑通」从不关注内存是怎么被管理的。等到项目上线、数据量变大突然遇到内存暴涨、程序卡顿、OOM崩溃才慌手慌脚去查原因。实际上Python 自带一套极其成熟的内存管理机制核心就是两大块引用计数和垃圾回收。这不仅是面试高频考点更是写出高性能、稳定Python程序的基础。2026年的今天Python 3.12 已经成为主流内存机制在细节上不断优化但底层核心逻辑依然没变。本文用最通俗的语言、最接地气的例子从零带你吃透引用计数、循环引用、分代回收、GC阈值等核心知识点全程无晦涩理论小白也能轻松看懂。一、先搞懂Python 里的对象到底是什么在讲内存管理之前我们必须先达成一个共识在Python中一切皆对象。不管是整数、字符串、列表、字典还是你自己定义的类实例全都是对象。每个对象在内存里都占一块空间并且有三个核心信息值对象存储的数据类型int / str / list 等引用计数记录有多少个变量在「指向」这个对象Python 不会让你手动 malloc / free它自动帮你管理没人用的对象 → 自动清理有人用的对象 → 保留判断「要不要删」的核心依据就是引用计数。二、引用计数Python 内存管理的基石2.1 引用计数是什么一句话引用计数 指向这个对象的「指针数量」。每多一个变量名绑定到对象计数1每少一个绑定计数-1计数变为0 → 对象立即被销毁内存归还系统。举个最简单的例子a[1,2,3]# 列表对象创建引用计数 1ba# b也指向同一个列表计数 2ca# 计数 3dela# 删除a计数 2b100# b指向新对象原列表计数 1cNone# c不再指向计数 0# 此时列表对象被立刻回收内存释放这就是引用计数最朴素的工作流程。2.2 哪些行为会改变引用计数在2026年的Python 3.12中以下操作依然严格影响引用计数引用计数 1 的场景对象被创建a 666对象被赋值给其他变量b a对象作为参数传入函数func(a)对象存入容器list.append(a)、dict[k] a引用计数 -1 的场景变量被显式删除del a变量重新赋值a 新对象变量离开作用域函数结束、代码块结束容器被销毁内部对象引用减少2.3 如何手动查看引用计数Python 提供内置模块sys.getrefcount()可以查看计数。注意调用函数本身会临时1所以看到的值会比真实多1。importsys obj[1,2,3]print(sys.getrefcount(obj))# 输出 2真实1函数调用1aobjprint(sys.getrefcount(obj))# 输出 3真实2这个函数在调试内存泄漏时非常实用。2.4 引用计数的优点与缺点优点实现简单、直观实时性强计数为0立即释放不会卡顿对程序整体运行影响均匀不会突然STWStop The World缺点致命无法处理循环引用每次赋值、删除都要更新计数有一定性能开销这就是为什么Python必须在引用计数之外再引入垃圾回收GC。三、循环引用引用计数的死穴3.1 什么是循环引用当两个或多个对象互相引用形成闭环就算外部没有任何指向它们的引用计数永远 ≥1永远不会被释放。经典示例a[]b[]a.append(b)b.append(a)deladelb执行del a和del b后外部没有任何变量指向a、b但 a 引用 bb 引用 a两者引用计数都为1永远不为0内存永远占着 →内存泄漏引用计数对此完全无能为力。3.2 循环引用在实际代码中多吗非常多双向链表树结构父子互指类实例互相引用闭包、装饰器嵌套大型业务对象互相依赖如果没有垃圾回收Python 程序跑久了必然内存爆炸。所以从 Python 2.0 开始官方引入了分代垃圾回收机制专门解决循环引用。四、Python 垃圾回收GC专门干掉循环引用Python GC 主要做一件事扫描并识别循环引用的孤立对象然后强制回收。它由三部分组成标记-清除解决循环引用分代回收优化扫描效率可配置阈值控制GC触发频率4.1 标记-清除算法原理流程非常简单遍历所有GC跟踪的对象把所有对象引用计数复制一份临时副本遍历每个对象对它引用的对象临时计数-1消除循环临时计数0 → 说明是不可达对象垃圾统一回收这些垃圾本质通过临时副本绕开循环引用找出真正没人用的对象。缺点扫描全对象耗时随对象数量增加会造成短暂STW程序短暂停顿所以Python做了优化分代回收。4.2 分代回收核心思想「活越久越不是垃圾」这是一种空间换时间的优化策略基于统计学规律新生对象大概率很快死亡老对象大概率继续存活。Python把对象分为三代第0代新生对象扫描最频繁第1代从0代存活下来的对象第2代从1代存活下来的老对象扫描最少GC规则0代满 → 触发0代GC活下来升1代1代达到阈值 → 触发1代GC活下来升2代2代扫描频率最低因为老对象很少变垃圾这样大幅减少扫描总量提升性能。4.3 2026年Python默认GC阈值真实可查在 Python 3.12 中默认阈值为importgcprint(gc.get_threshold())# 输出 (700, 10, 10)含义0代对象超过700→ 触发0代GC0代GC执行超过10次→ 触发1代GC1代GC执行超过10次→ 触发2代GC你可以手动调整gc.set_threshold(1000,15,15)4.4 手动控制GC常用GC接口2026年依然有效importgc gc.enable()# 开启GC默认开启gc.disable()# 关闭GC高性能场景可用gc.collect()# 立即手动全代回收gc.get_threshold()# 获取阈值gc.set_threshold()# 设置阈值gc.garbage# 查看无法回收的不可达对象极少出现注意手动关闭GC只推荐极度性能敏感场景普通业务不要乱关。五、Python 3.12 内存优化新特性2026年最新到了2026年Python 3.12、3.13 在内存管理上做了大量真实优化重点如下5.1 更快的分配器obmalloc 优化Python 内置内存分配器持续优化小对象分配更快、碎片更少。5.2 引用计数操作原子化多核安全在多线程场景下引用计数更新更安全减少竞争开销。5.3 GC 暂停时间进一步降低对循环引用的扫描流程做了裁剪减少STW时间对Web服务、实时脚本更友好。5.4 对“短命临时对象”更友好列表推导、生成器表达式创建的临时对象回收更快。这些优化都是真实存在、官方文档可查没有任何虚构。六、实战写出更省内存的Python代码理解了引用计数和GC你就可以写出内存更优雅的代码。6.1 避免不必要的对象创建坏foriinrange(100000):sstr(i)_test每次循环都新建字符串大量临时对象。好base_testforiinrange(100000):sf{i}{base}减少中间对象。6.2 及时删除大对象big_dataload_large_file()process(big_data)delbig_data# 立即释放6.3 避免隐性循环引用classA:def__init__(self):self.bNoneclassB:def__init__(self):self.aNoneaA()bB()a.bb b.aa使用完尽量手动断开a.bNoneb.aNonedeladelb6.4 使用弱引用 weakref对于缓存、观察者模式用weakref不增加引用计数避免循环引用。6.5 生产环境建议大内存服务适当调大GC阈值短脚本可手动gc.collect()长期后台服务开启GC配合监控出现内存泄漏用objgraph、tracemalloc定位七、常见面试题总结2026年依然高频Python内存管理核心是什么引用计数 分代垃圾回收。引用计数缺点是什么无法处理循环引用有一定性能开销。GC如何解决循环引用标记-清除 分代回收。分代回收的依据是什么新生对象死亡率高老对象更稳定。del关键字到底做了什么减少引用计数不保证立即回收。gc.collect()做什么强制执行垃圾回收清理循环引用。八、总结Python 内存管理看似底层实则决定了程序的稳定性、并发能力、内存占用。引用计数实时、简单负责大部分普通对象回收垃圾回收专门解决循环引用分代优化效率2026年Python 3.12 在分配、GC暂停上持续优化理解原理才能写出无泄漏、高性能代码不管是面试、日常开发还是线上调优这都是必须掌握的核心基础。P.S. 无意间发现了一个巨牛的人工智能教程非常通俗易懂对AI感兴趣的朋友强烈推荐去看看[传送门https://blog.csdn.net/HHX_01](https://blog.csdn.net/HHX_01/article/details/159613021)