IronPython 垃圾收集 - 它如何提供与 C 扩展的兼容性?

问题描述 投票:0回答:2

在 Larry Hastings 的 GIL 演讲的这一部分中,解释了 ironclad 如何提供与 IronPython 的 C 扩展兼容性。这是演讲中有趣的部分

我们实现了一个叫做 Ironclad 的东西,这是一个实现 IronPython 的 Python C-API 和 IronPython 没有 GIL 它不使用引用计数,但我们维护二进制 与现有二进制文件的兼容性。

这些现有的二进制文件所拥有的是 C 对象 (实际上是用 C 实现的 python 对象)期望使用 引用计数所以我们有一个混合系统。对于那些曾经是 从 C 扩展返回,我们人为地夸大了它们的引用 按 1 计数,以便编译到二进制文件中的macros 永远不会因为降到零而被触发,然后我们就有了一个代理 object 如果这个对象进入了垃圾回收,那么我们 会将引用计数减少到零。

从技术上讲,我们存在泄漏,因为如果您传递对 python 反对 C 扩展,C 扩展可以保留 提到那些活着的人,基本上拉里所说的是 如果你转向类似 Mark 的东西并扫描主要的 python C 解释器中,那些 C 对象对于垃圾收集器来说是不透明的。 它无法知道你有什么内部参考。

我的问题:

1- 如果 GC 是在解释器本身(例如 IronPython)中实现的,那么他所指的宏是什么? (我们应该关心这一点并为此增加引用计数!)

2- 代理对象的作用是什么?它是在 C 扩展中实现的 python 对象的代理?为什么我们不直接减少原始对象的引用计数呢?

python garbage-collection ironpython python-c-api reference-counting
2个回答
1
投票
  1. 他所指的宏是在C端使用的Python-C API宏。

  2. 代理对象的作用是在CPython的引用计数GC和IronPython的.Net GC之间进行转换。

这是一门高级科目。如果您不熟悉这两个 Python 实现,这些答案可能对您没有帮助。但这里没有简单的答案。


0
投票

模块可以做任何实际的事情。某些模块在方法/函数调用期间保留对象,例如当计算可能更长时。在普通的Python中。在这种情况下,对象应该向引用计数加一,直到完成为止。

在非常基础的层面上,Python 对象的引用计数是 每当对象被引用时就会递增,并且会递减 当对象被取消引用时。如果一个对象的引用计数为0, 对象的内存被释放。你的程序代码不能 禁用 Python 的引用计数。

例如你有三种方法。

start_calculation(data)
get_finished_calculations()

调用第一个会在某些模块堆栈上设置数据并保留一些Python对象,数据的引用计数应该增加1。当最终由 get_finished_calculations 返回结果时,引用计数将减少。但因为这些堆栈位于 C 模块一侧,在 .Net 术语中被视为非托管代码,垃圾收集器无法看到它,并且即使模块仍然需要进行计算也会删除数据,因为 IronPython 也没有像 CPython 那样的引用计数有。

© www.soinside.com 2019 - 2024. All rights reserved.