垃圾回收机制 | Python

简介: Python 的垃圾回收机制采用“引用计数”为主,“分代回收”和“标记-清除”为辅的策略。引用计数通过跟踪对象的引用次数,实时释放无引用对象的内存,但存在循环引用问题。分代回收将对象按存活时间分为三代,优先回收短命对象,减少性能开销。标记-清除技术用于解决容器对象的循环引用问题,通过标记不可达对象并清除它们,但需全量扫描堆内存,效率较低。这三种机制共同确保 Python 内存管理的高效与稳定。

python采用的是引用计数机制为主,分代回收(隔代回收)标记-清除两种机制为辅的策略。

引用计数机制

正是因为有引用,对象才会在内存中存在。

引用计数是一种非常高效的内存管理手段,当一个pyhton对象被引用时其引用计数增加1,当其不再被引用时引用计数减1,当引用计数等于0的时候,对象就被删除了。

优点

  1. 实现简单。
  2. 垃圾回收的实时性。一旦没有引用,内存被直接释放;分摊处理内存回收的时间。

缺点

  1. 使用额外内存维护引用计数
  2. 循环引用导致内存泄漏

导致对象的引用计数+1的情况

  1. 创建对象
  2. 对象被引用
  3. 对象作为参数,传入到函数中
  4. 对象作为容器的元素,如l = [a, a]

导致对象的引用计数-1的情况

  1. 引用被重新赋值
  2. 引用被del,del删除的是引用,而不是对象
  3. 超过作用域
  4. 元素所在的容器被销毁

分代回收

从理论上说,对象的创建数目==释放数目。但是如果存在循环引用的话,肯定是创建>释放数量,当创建数与释放数量的差值达到规定的阈值的时候,当当当当~分代回收机制就登场啦。

Python根据对象的存活时间将内存划分为年轻代、中年代和老年代,分别用0,1,2表示。

越年轻的对象越容易死掉,老的对象通常会存活更久。 新生的对象被放入0代,如果该对象在第0代的一次gc垃圾回收中活了下来,那么它就被放到第1代里面(它就升级了)。如果第1代里面的对象在第1代的一次gc垃圾回收中活了下来,它就被放到第2代里面。

分代回收算法

  1. 从上一次第0代gc后,如果分配对象的个数减去释放对象的个数大于threshold0,那么就会对第0代中的对象进行gc垃圾回收检查。
  2. 从上一次第1代gc后,如果第0代被gc垃圾回收的次数大于threshold1,那么就会对第1代中的对象进行gc垃圾回收检查。
  3. 从上一次第2代gc后,如果第1代被gc垃圾回收的次数大于threshold2,那么就会对第2代中的对象进行gc垃圾回收检查。

gc.set_threshold(threshold0[, threshold1[, threshold2])设置各代执行垃圾回收的阈值。

有三种情况会触发垃圾回收:

  1. 调用gc.collect(),显式进行垃圾回收;
  2. 当gc模块的计数器达到阈值的时候;
  3. 程序退出的时候。

分代回收是建立在标记清除技术基础之上。分代回收同样作为Python的辅助垃圾收集技术处理那些容器对象,因为对于字符串、数值对象是不可能造成循环引用问题。

标记清除技术

标记清除用来解决循环引用产生的问题,循环引用只有在容器对象才会产生,比如字典,元祖,列表等。

在标记清除算法中有两个链表,root链表和unreachable链表。unreachable链表中的对象会被回收。

为什么设置两个链?

unreachable链表中可能存在被root链表中的对象、直接或间接引用的对象,这些对象是不能被回收的,一旦在标记的过程中,发现这样的对象,就将其从unreachable链表中移到root链表中;当完成标记后,unreachable链表中剩下的所有对象就是名副其实的垃圾对象了,接下来的垃圾回收只需限制在unreachable链表中即可。

Python使用一个双向链表将这些容器对象组织起来。不过,这种简单粗暴的标记清除算法也有明显的缺点:清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。


转载来源:https://juejin.cn/post/6844904115911262216

相关文章
|
算法 Java Python
|
存储 Java 程序员
【Python 的内存管理机制专栏】深入解析 Python 的内存管理机制:从变量到垃圾回收
【5月更文挑战第18天】Python内存管理关乎程序性能与稳定性,包括变量存储和垃圾回收。变量存储时,如`x = 10`,`x`指向内存中值的引用。垃圾回收通过引用计数自动回收无引用对象,防止内存泄漏。了解此机制可优化内存使用,避免循环引用等问题,提升程序效率和稳定性。深入学习内存管理对成为优秀Python程序员至关重要。
133 5
【Python 的内存管理机制专栏】深入解析 Python 的内存管理机制:从变量到垃圾回收
|
12月前
|
Java Python
Python进阶之旅:深入理解变量作用域、垃圾回收、拷贝机制与异常处理
Python进阶之旅:深入理解变量作用域、垃圾回收、拷贝机制与异常处理
|
算法 Java 程序员
Python专家解读垃圾回收<<二>>
Python专家解读垃圾回收<<二>>
Python专家解读垃圾回收<<二>>
|
算法 Java 程序员
Python内存管理:请解释Python中的引用计数机制以及如何处理循环引用。描述一下Python是如何通过垃圾回收来释放不再使用的对象内存的。
Python内存管理:请解释Python中的引用计数机制以及如何处理循环引用。描述一下Python是如何通过垃圾回收来释放不再使用的对象内存的。
193 1
|
算法 Java 开发者
99 python高级 - 垃圾回收(二)
99 python高级 - 垃圾回收(二)
110 0
|
Java Python
98 python高级 - 垃圾回收(一)
98 python高级 - 垃圾回收(一)
66 0
|
算法 Java Python
Python专家解读垃圾回收<<三>>
Python专家解读垃圾回收<<三>>
Python专家解读垃圾回收<<三>>
|
算法 Java C#
Python专家解读垃圾回收<<一>>
Python专家解读垃圾回收<<一>>
|
Java Python
Python垃圾回收
Python垃圾回收自制脑图 就像我们生活会产生垃圾一样,程序在运行过程中也会产生垃圾。 在程序中没有被引用的对象就是垃圾。程序运行过程中产生的垃圾会影响到程序的运行性能,所以这些垃圾清理必须被及时清理。所谓的垃圾回收就是将垃圾从内存中删除。 在 Python 中有自动的机回收机制,他会将这些没有被引用的对象删除,所以我们不用手动处理垃圾回收。
165 1
Python垃圾回收

热门文章

最新文章