Python中的引用计数
有两个宏 Py_INCREF(x) 和 Py_DECREF(x) ,会处理引用计数的增减。 Py_DECREF() 也会在引用计数到达0时释放对象。为了灵活,并不会直接调用 free() ,而是通过对象的 类型对象 的函数指针来调用。为了这个目的(或其他的),每个对象同时包含一个指向自身类型对象的指针。
最大的问题依旧:何时使用 Py_INCREF(x) 和 Py_DECREF(x) ?我们首先引入一些概念。没有人"拥有"一个对象,你可以 拥有一个引用 到一个对象。一个对象的引用计数定义为拥有引用的数量。引用的拥有者有责任调用 Py_DECREF() ,在引用不再需要时。引用的拥有关系可以被传递。有三种办法来处置拥有的引用:传递、存储、调用 Py_DECREF() 。忘记处置一个拥有的引用会导致内存泄漏。
还可以 借用 2 一个对象的引用。借用的引用不应该调用 Py_DECREF() 。借用者必须确保不能持有对象超过拥有者借出的时间。在拥有者处置对象后使用借用的引用是有风险的,应该完全避免 3 。
借用相对于引用的优点是你无需担心整条路径上代码的引用,或者说,通过借用你无需担心内存泄漏的风险。借用的缺点是一些看起来正确代码上的借用可能会在拥有者处置后使用对象。
借用可以变为拥有引用,通过调用 Py_INCREF()。 这不会影响已经借出的拥有者的状态。 这会创建一个新的拥有引用,并给予完全的拥有者责任(新的拥有者必须恰当的处置引用,就像之前的拥有者那样)。 |