当前位置: 首页 > 图灵资讯 > 行业资讯> Python中的垃圾回收机制是什么

Python中的垃圾回收机制是什么

发布时间:2025-10-19 21:22:26

一、写在前面:

众所周知,Python是一种面向对象的脚本语言,对象是Python中一个非常重要的概念。在Python中,数字是对象,字符串是对象,一切都是对象,它们的核心是结构。--PyObject。

typedefstruct_object{
  intob_refcnt;
  struct_typeobject*ob_type;
}PyObject;

Pyobject是每个对象的必备内容,其中ob_refcnt作为引用计数。

二、垃圾回收机制

垃圾回收(Garbage Collection)每个人都应该或多或少地听说过,但什么是垃圾回收呢?我们在这里说的垃圾回收肯定不是把垃圾扔进垃圾桶。现在的高级语言Java,C#所有这些都采用了垃圾回收机制,而不是C,C++用户可以自行管理和维护内存,但可能会出现内存泄漏、悬挂指针等问题。垃圾回收机制作为一种现代编程语言的自动内存管理机制,专注于两件事:1. 在内存中找到无用的垃圾资源 2. 清除垃圾并将内存转移给其他对象。

相关推荐:Python视频教程

三、Python中的垃圾回收

在Python中,垃圾回收机制主要以引用计数为主要手段,以标记清除和分代回收机制为辅助手段。

1、引用计数

通过之前的介绍,我们已经知道Pyobject是每个对象的必备内容,当一个对象有新的引用时,它的ob_refcnt就会增加,当引用对象被删除时,它的ob_refcnt就会减少,当引用计数为0时,对象的生命就会结束。

让我们来看看引用计数+1的情况:

(1)创建对象:

zz.png

事实上,这里的123对象并没有在内存中新建,因为在Python启动解释器时,会创建一个小的整数池,在-5~256之间的整数对象会自动加载到内存中等待调用。因此,a=123是对123整数对象的引用。456不在整数池中,需要创建对象,最终引用次数为2?因为sys.getrefcount(b)也是引用。

(2)引用对象:

xx.png

每次赋值操作都会增加数据的引用次数,记住引用的变量a、b、c指的是数据456,而不是变量本身。

(3)将对象作为参数传输到函数中:

cc.png

很明显,引用计数在传输到函数后增加了1。

(4)将对象作为元素储存在容器中:

vv.png

在这里,我们在创建对象后,将a分别添加到一个列表和一个元组中,并增加了引用计数。

虽然引用计数必须添加管理引用计数操作,但与其他垃圾回收技术相比,引用计数具有“实时”的优点,如果对象没有引用,内存直接释放,其他垃圾回收技术必须在一定的特殊条件下无效内存回收。然而,引用计数带来的维护引用计数的额外操作与Python中的内存分配和释放成正比。此外,引用计数机制还有一个弱点——循环引用带来的问题无法解决。循环引用可以使引用对象的引用计数不是0,但这些对象实际上没有被任何外部对象引用,它们只是相互引用,这意味着对象占用的内存空间应该回收,但引用计数不是0,所以对象占用的内存空间永远不会释放。如下所示,列表1和列表2相互引用。如果没有其他对象引用它们,列表1和列表2的引用计数仍然是1,占用的内存将永远无法回收,这将是致命的。

list1=[]
list2=[]
list1.append(list2)
list2.append(list1)

2、标记清除

标记清除(Mark—Sweep)基于跟踪回收的算法(tracing GC)技术实现的垃圾回收算法。分为两个阶段:第一阶段是标记阶段,GC会标记所有活动对象,第二阶段是回收没有标记的非活动对象。

对象通过引用(指针)连接在一起,形成一个有向图,对象构成这个有向图的节点,引用关系构成这个有向图的边缘。从根对象(root object)出发,沿着有向边经历的对象,可以达到(reachable)对象标记为活动对象,未达到的对象是要清除的非活动对象。根对象为全局变量、调用栈、寄存器。 

1562145716(1).png        

在上图中,您可以直接从程序变量访问块1,并间接访问块2和3。程序不能访问块4和5。第一步是标记块1,并记住块2和3以供以后处理。第二步是标记块2,第三步是标记块3,但不要记住块2,因为它已经被标记了。扫描阶段将忽略块1、2和3,因为它们已经被标记,但将回收块4和5。

作为Python的辅助垃圾收集技术,标记清除算法主要处理一些容器对象,如列表、dict、tuple等,因为不可能引起字符串和值对象的循环引用。Python使用双向链表组织这些容器对象。然而,这种简单而粗糙的标记清除算法也有明显的缺点:在清除非活动对象之前,它必须按顺序扫描整个堆内存,即使只剩下一小部分活动对象。

3、分代回收

分代回收是以标记清除技术为基础的,是一种以空间换时间的操作模式。

Python根据对象的存活时间将内存分为不同的集合,每个集合称为一代,Python将内存分为三代“代”、中年(第一代)、在老年(第二代),它们对应于三个链表,它们的垃圾收集频率和对象的生存时间增加和减少。新对象将分布在年轻一代,年轻一代链表总数达到上限,Python垃圾收集机制将触发,那些可以回收对象,那些不能回收对象将移动到中年,等等,老对象是最长的生存对象,甚至在整个系统的生命周期。

相关文章

Python中的垃圾回收机制是什么

Python中的垃圾回收机制是什么

2025-10-19
Python之安装和环境配置

Python之安装和环境配置

2025-10-19
Python split()方法详解:分割字符串

Python split()方法详解:分割字符串

2025-10-19
Python常用模块之hashlib

Python常用模块之hashlib

2025-10-19
Python join()方法:合并字符串

Python join()方法:合并字符串

2025-10-19
Python dir()和help()帮助函数

Python dir()和help()帮助函数

2025-10-19