Python';垃圾收集器是否检测循环引用?
我试图理解Python的垃圾收集器是如何检测循环引用的。当我查看文档时,我看到的只是一条语句,即检测到循环引用,除非所涉及的对象具有Python';垃圾收集器是否检测循环引用?,python,garbage-collection,cpython,Python,Garbage Collection,Cpython,我试图理解Python的垃圾收集器是如何检测循环引用的。当我查看文档时,我看到的只是一条语句,即检测到循环引用,除非所涉及的对象具有\uu del\uu方法 如果发生这种情况,我的理解(可能是错误的)是gc模块通过(我假设)遍历所有分配的内存并释放任何无法访问的块来充当故障保护 Python在使用gc模块之前如何检测和释放循环内存引用 Python在使用gc模块之前如何检测和释放循环内存引用 没有。gc的存在只是为了检测和释放循环引用。非循环引用通过refcounting处理 现在,要查看gc如
\uu del\uu
方法
如果发生这种情况,我的理解(可能是错误的)是gc模块通过(我假设)遍历所有分配的内存并释放任何无法访问的块来充当故障保护
Python在使用gc模块之前如何检测和释放循环内存引用
Python在使用gc模块之前如何检测和释放循环内存引用
没有。gc的存在只是为了检测和释放循环引用。非循环引用通过refcounting处理
现在,要查看gc如何确定任何给定对象引用的对象集,请查看Modules/gcmodule.c
中的gc\u get\u references
函数。相关比特是:
//其中'obj'是我们要查找的引用对象
遍历过程遍历;
如果(!PyObject_是_GC(obj))
继续;
导线=Py_型(obj)->tp_导线;
如果(!遍历)
继续;
if(遍历(obj,(visitproc)参考访问,结果)){
Py_DECREF(结果);
返回NULL;
}
这里的主要功能是tp\u遍历
。每个C级类型定义一个tp\u遍历
函数(如果对象不包含任何引用,如str
,则将其设置为NULL
)。tp\u遍历
的一个例子是list\u遍历
,它是list
的遍历函数:
static int
列表遍历(PyListObject*o,visitproc-visit,void*arg)
{
Py_ssize_t i;
对于(i=Py_SIZE(o);--i>=0;)
Py_访问(o->ob_项目[i]);
返回0;
}
我看到的是一条语句,循环引用被检测到,除非所涉及的对象具有\uu del\uu()
方法
您是对的-Python的周期检测器可以检测和收集周期,除非它们包含具有\uu del\uu
方法的对象,因为解释器无法安全地删除这些对象(为了直观地了解原因,假设有两个对象具有相互引用的\uu del\uu
方法。它们应该按什么顺序释放?)
当带有\uuu del\uuu
方法的对象涉及到一个循环时,垃圾收集器将把它们放在一个单独的列表中(可通过访问),以便程序员可以手动“处理”它们
Python在使用gc模块之前如何检测和释放循环内存引用
Python的垃圾收集器(实际上不是gc
模块,它只是垃圾收集器的Python接口)实现了这一点。因此,Python在使用垃圾收集器之前不会检测并释放循环内存引用
Python通常在大多数对象的引用计数达到零时释放它们。(我说“most”是因为它从不释放,例如,小整数或内部字符串。)在循环引用的情况下,这种情况永远不会发生,因此垃圾收集器会周期性地遍历内存并释放循环引用的对象
当然,这些都是特定于CPython的。其他Python实现有不同的内存管理(Jython=Java VM,IronPython=Microsoft.NET CLR)。我想我在@SvenMarnich对原始问题的评论中找到了我想要的答案: 容器对象是可以保存对其他Python对象的引用的Python对象。列表、类、元组等是容器对象;整数、字符串等不是。因此,只有容器对象存在循环引用的风险 每个Python对象都有一个字段-*gc_ref*,对于非容器对象,它(我相信)被设置为NULL。对于容器对象,它被设置为等于引用它的非容器对象的数量 任何*gc_ref*计数大于1的容器对象(我本以为是0,但现在还可以?)都有非容器对象的引用。因此,它们是可访问的,并且不被认为是不可访问的内存岛 由已知可访问的对象(即我们刚刚识别为*gc_ref*计数大于1的对象)可访问的任何容器对象也不需要释放 其余的容器对象不可访问(彼此除外),应该释放它们 链接是否提供了更全面的解释
是到源代码的链接,其中有注释进一步解释循环引用检测背后的思想。但不保证收集包含循环引用的垃圾说。你能链接你所指的文档页面吗?这是我正在阅读的页面:我在链接页面上找不到许可证,所以我不确定是否可以将较长的文章从该页面复制到so。如果不复制内容,。我不会写摘要,所以请继续。顺便说一句,我找到了链接。还有其他链接没有o相关邮件列表线程。垃圾收集器的基本概念似乎没有改变。不完全准确。Python不会遍历内存并释放无法访问的对象。它遍历内存并检测引用周期,然后释放这些引用周期。它是否“遍历内存”?我以为它遍历了引用列表?(还是“遍历内存”)有我不熟悉的技术定义吗?)
gc
模块是循环垃圾收集器。它不仅是Python接口,也是实现。默认情况下,gc
模块不在sys.modules中,而其他一些实现内置在Python中的模块则在sys.modules中,因此我假设gc
模块就是实现。感谢您的更新。I在文档中,我看到了下面的语句:“