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

  介绍

这篇文章主要介绍了Python中垃圾回收机制指的是什么,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。

<强>一,写在前面:

我们都知道Python一种面向对象的脚本语言,对象是Python中非常重要的一个概念。在Python中数字是对象,字符串是对象,任何事物都是对象,而它们的核心就是一个结构体——PyObject。

typedef  struct_object {   int  ob_refcnt;   struct_typeobject  * ob_type;   }PyObject;

PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。

<强>二、垃圾回收机制

垃圾回收(垃圾收集)大家应该多多少少都听过,但是什么是垃圾回收呢?我们这里说的垃圾回收肯定不是把垃圾丢进垃圾桶。现在的高级语言Java、c#等,都采用了垃圾回收机制,而不再是C, c++里用户自己管理维护内存的方式,自己管理内存是很自由,但是可能出现内存泄漏,悬空指针等问题。而垃圾回收机制作为现代编程语言的自动内存管理机制,专注于两件事:1。找到内存中无用的垃圾资源2。清除这些垃圾并把内存让出来给其他对象使用。

三、Python中的垃圾回收

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

1、引用计数

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

我们来看看引用计数+1的情况有什么:

(1)对象被创建:

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

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

(2)对象被引用:

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

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

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

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

这里可以很明显看到在被传递到函数中后,引用计数增加了1。

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

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

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

虽然引用计数必须在每次分配合释放内存的时候加入管理引用计数的操作,然而与其他垃圾回收技术相比,引用计数有一个最大的优点,那就是“实时性”,如果这个对象没有引用,内存就直接释放了,而其他垃圾回收技术必须在某种特殊条件下才能进行无效内存的回收。但是引用计数带来的维护引用计数的额外操作和Python中进行的内存分配和释放,引用的赋值次数成正比的。除此之外,引用计数机制的还有一个最大的软肋--无法解决循环引用带来的问题。循环引用可以使一种引用对象的引用计数不为0,然而这些对象实际上并没有被任何外部对象所引用,它们之间只是相互引用,这意味着这组对象所占用的内存空间是应该被回收的,但是由于循环引用导致的引用计数不为0,所以这组对象所占用的内存空间永远不会被释放。如下,list1与list2相互引用,如果不存在其他对象对它们的引用,list1与list2的引用计数也仍然为1,所占用的内存永远无法被回收,这将是致命的。

list1 = []
  时间=list2  []
  list1.append(用于)
  list2.append (list1) 

2,标记清除

标记清除(标记-清除)算法是一种基于追踪回收(跟踪GC)技术实现的垃圾回收算法。它分为两个阶段:第一阶段是标记阶段,GC会把所有的活动对象打上标记,第二阶段是把那些没有标记的对象非活动对象进行回收。

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