Python中的垃圾收集

2025-06-07

Python中的垃圾收集

在 C 或 C++ 等语言中,程序员负责在堆上动态分配和释放内存。但在 Python 中,程序员无需预分配或释放内存。

Python 使用以下垃圾收集算法进行内存管理 -

  • 引用计数

  • 循环检测算法(循环引用)

引用计数

引用计数是一个简单的过程,当程序中不再引用被引用的对象时,该对象会被释放。
简而言之,当引用计数达到 时0,该对象就会被释放(释放其分配的内存)。

让我们看看下面的例子 -

def calculate_sum(num1, num2):
    total = num1 + num2
    print(total)
Enter fullscreen mode Exit fullscreen mode

在上面的例子中,我们有三个局部引用num1num2total。这里与total不同,因为它只在块内部引用,因此其引用计数为 1,在块外部引用,因此它们的引用计数可能不止 1。num1num2num1num2

因此,当函数执行完毕后,引用计数total减少到0。因为它被垃圾收集器跟踪了。

垃圾收集器发现total不再被引用(引用计数字段达到0)并释放其分配的内存。

在函数外部声明的变量,即使函数执行完毕后也不会被销毁。

我们也可以使用del语句手动删除变量。del该语句会删除一个变量及其引用。当引用计数达到 时0,它将被垃圾收集器回收。

引用计数算法也存在一些问题,例如循环引用 -

循环引用

当一个或多个对象相互引用时,就会发生引用循环。

替代文本

如上图所示,list对象 指向自身,并且object1object2相互指向。此类对象的引用计数始终至少为1

让我们开始实际操作吧——

import gc

gc.set_debug(gc.DEBUG_SAVEALL) 

lst = []
lst.append(lst)

lst_address = id(lst)

del lst

object_1 = {}
object_2 = {}
object_1['obj2'] = object_2
object_2['obj1'] = object_1

obj_address = id(object_1)

del object_1, object_2
Enter fullscreen mode Exit fullscreen mode

在上面的例子中,该del语句删除了变量及其对对象的引用。

让我们检查一下,它使用删除了变量gc.collectgc.collect并将其保存到而gc.garbage不是删除。

>>> gc.collect()
3
Enter fullscreen mode Exit fullscreen mode

当我们删除一个变量时,我们只是删除了它的__main__引用。现在我们根本无法访问lstobject_1object_2,但是这些变量仍然有 1 个引用,这意味着引用计数为 1,引用计数算法不会回收它。

检查参考计数如下-

import sys
print(sys.getrefcount(obj_address))
print(sys.getrefcount(lst_address))

2
2
# 1 from the variable and 1 from getrefcount
Enter fullscreen mode Exit fullscreen mode

将此数字乘以 100 万个对象,您可能会遇到严重的内存泄漏问题。

对于这种引用循环,Python 有另一个专门用于发现和销毁循环引用的算法。它也是Python GC中唯一可控的部分。

概括

Python 有两种垃圾回收算法。一种用于处理引用计数,当引用计数达到上限时0,它会移除对象并释放其分配的内存。另一种是循环检测算法,用于发现并销毁循环引用。

我希望您现在对 Python 中的垃圾收集算法有了一定的了解。

如果您有任何建议,请在评论中告诉我。

参考

https://rushter.com/blog/python-garbage-collector/

文章来源:https://dev.to/sharmapacific/garbage-collection-in-python-1d4g
PREV
在 React 中裁剪和调整图像大小
NEXT
二进制文件 “二进制”文件和“文本”文件之间的区别