1.10.1 Python中的引用计数
有两个宏,Py_INCREF(x)
和 Py_DECREF(x)
, 用来处理增加和减少引用计数。 Py_DECREF(x)
也可以在引用计数为0时释放对象。为灵活起见,它却不直接调用free(),它通过对象中的type object函数指针调用。为此(也有其他目的),每个对象也都包含指向本身类型对象的指针。
现在,最大的问题是:什么时候使用Py_INCREF(x)
和 Py_DECREF(x)
?让我们首先介绍一些术语。没有人’拥有’(own a reference) 一个对象;然而,你可以拥有对象的一个引用。现在,一个对象的引用计数被定义为一个拥有对它引用的个数。引用的拥有者负责在不在需要引用时调用Py_DECREF(x)
。引用关心可以被转移。有三种方式处理拥有的引用:传递它,保存它,或者调用Py_DECREF(x)
。忘记处理拥有的引用则产生内存泄漏。
也可以借用 一个对象的引用。引用的借用者不必调用Py_DECREF(),借用者不能保持对象比拥有者还长。借用引用这种用法,在拥有者已经清除引用后,存在使用’已释放内存’的风险,应完全避免。
借用拥有者的引用的优点是你不必在代码的任何路径中关心引用的清除-换句话说,使用借用引用,你就不必冒提前退出时内存泄漏的风险。使用借用防止内存泄漏的缺点是在一些细微的看起来正确的代码的条件下,
借用引用在拥有者实际已经清除引用后,还能被使用。借用引用通过调用tt class="cfunction">Py_INCREF()能够被改变成拥有。这不影响拥有者(被借用引用的拥有者)引用的状态-它创建新的拥有的引用,并给予全部的拥有者的能力(新的拥有者必须正确地清除引用,就象前面的拥有者那样)。