为什么python对gc同时使用引用计数和标记和扫描



我的问题是,为什么python同时使用引用计数和标记并扫描gc?为什么不只是标记和扫?

我最初的猜测是,使用引用计数可以很容易地删除非循环引用对象,这可能会在一定程度上加快标记和扫描速度,并立即获得内存。不知道我的猜测是否正确?

有什么想法吗?

非常感谢。

Python(该语言)没有说明它使用哪种形式的垃圾收集。主要实现(通常称为CPython)的作用与您描述的一样。Jython或IronPython等其他版本使用纯垃圾收集系统。

是的,早期收集引用计数有好处,但CPython使用它的主要原因是历史原因。最初没有针对循环对象的垃圾收集,因此循环会导致内存泄漏。C API和数据结构主要基于引用计数的原理。当添加真正的垃圾收集时,不能选择破坏现有的二进制API和所有依赖它们的库,因此必须保留引用计数。

引用计数比垃圾收集更早地释放对象

但是,由于引用计数无法处理不可访问对象之间的引用循环,Python使用垃圾收集器(实际上只是一个循环收集器)来收集那些存在的循环。

我最初的猜测是,使用引用计数可以很容易地删除非循环引用对象,这可能会在一定程度上加快标记和扫描速度,并立即获得内存。不知道我的猜测是否正确?

是的。只要refcount变为零,就可以移除对象。这不会发生在循环引用的对象中。AFAIK,标记和扫描是一项成本高昂的操作,实现它的最简单方法需要在标记对象时"停止世界"。当遍历所有对象时,未标记(可访问)的andy对象将被释放。