尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python.四.(一)--1.内存管理与底层原理

Python.四.(一)--1.内存管理与底层原理 Python的垃圾回收机制介绍一下Python中的引用计数原理如何消除一个变量上的所有引用计数Python中什么情况下会产生内存泄漏Python的深拷贝与浅拷贝Python中removedel以及pop之间的区别Python 内存管理与底层原理串讲这几个问题本质上都指向同一套底层机制对象的引用计数 分代回收 拷贝语义 容器操作对引用的增减。下面逐点拆解再统一收口。1. 垃圾回收机制三层结构 Python 的 GC 不是单一机制而是三层组合引用计数Reference Counting每个对象头里有一个ob_refcnt字段被引用 1引用失效 -1。归零即立即回收——这是主回收路径响应快、时机确定。标记-清除Mark Sweep专门处理引用计数无能为力的循环引用如a.bb; b.aa从根对象出发做可达性分析。分代回收Generational GC把对象分成 0/1/2 三代新对象在第 0 代熬过回收则晋升。代龄越高触发频率越低基于越老越可能长存的经验。底层用gc模块控制后两者引用计数是自动且不可关的。2. 引用计数原理与清空引用 ⛓️引用计数针对的是对象不是变量名。变量名只是namespace里的一个键指向某对象。所谓消除某对象的所有引用本质是让所有指向它的名字、容器元素、属性都失效del x—— 删除名字绑定引用 -1x None/ 重新赋值 —— 旧绑定被替换引用 -1容器销毁或del lst[i]—— 容器内引用消失-1离开函数作用域 —— 局部名字自动失效-1当计数降到 0对象被立即回收若它还持有别的对象引用会级联减少下游计数。3. 内存泄漏的典型场景 CPython 有 GC但仍可能泄漏常见原因循环引用 __del__析构器旧版本里两者组合会让 GC 无法回收顺序不确定对象永久滞留。Python 3.4 虽已用 PEP 442 改善但仍应避免。长生命周期容器当缓存全局字典/列表只增不删引用一直挂着。闭包捕获大对象闭包持有外部变量只要闭包活着被捕获对象就不释放。C 扩展引用计数失误手动Py_INCREF/Py_DECREF配对错误。回调/监听器未注销注册后忘记反注册发布端持续持有回调所属对象。核心特征引用未归零 GC 也够不着如 C 层泄漏。4. 深拷贝 vs 浅拷贝 维度浅拷贝copy.copy()深拷贝copy.deepcopy()复制范围只复制最外层容器递归复制所有层级元素关系元素仍是同一对象共享元素是全新副本修改影响改元素会波及原对象改元素互不影响常见浅拷贝形式list[:]、list.copy()、list(lst)、dict.copy()。关键点浅拷贝把内部引用原样照搬所以引用计数整体 1针对被共享的元素对象深拷贝则创建全新对象链原对象计数基本不变除自身被引用外。5. del / remove / pop 区别 ✂️操作作用对象机制返回值异常del lst[i]索引/切片或名字语句删除绑定引用 -1无越界IndexErrorlst.remove(x)值方法删首个匹配项None找不到ValueErrorlst.pop([i])索引默认末尾方法删除并取出被删元素越界IndexErrordel最底层它直接作用于名字绑定或容器槽位本质是解除引用可连变量名本身一起删除。remove按值查找定位到槽位后再解除引用。pop等价于取出再 del返回值是它与del的关键区别。6. 统一收口它们如何串联 一条主线贯穿全部——引用对象生命周期 引用计数 GC。del语句、remove/pop操作底层都是修改ob_refcnt计数归零触发即时回收循环引用则交给分代 GC。拷贝改变引用拓扑。浅拷贝增加元素引用计数共享深拷贝重建拓扑独立选错拷贝方式会导致改一处动全身或意外延长对象寿命。内存泄漏 引用该断未断。无论是缓存、闭包还是 C 扩展本质都是某条引用链路没收掉让对象计数永远不归零、又不在 GC 可达图之外。del/remove/pop是断引用的三种姿势del最直接断绑定remove按值断、pop断且取。三者都通过减少引用计数参与内存回收。一句话总结Python 内存管理的全部底层逻辑就是围绕**“谁还引用这个对象”**这件事做文章——引用计数管即时回收GC 兜底循环引用拷贝与容器操作则在改变谁引用谁而del/remove/pop则是切断引用的具体工具。
返回列表