Python的引用计数

引用计数是内存管理的一种方法,将对象、内存等被引用的次数记录下来,当引用的次数变为0,就意味着不再有人使用它,可以将其释放。从而实现资源的自动管理。

引用计数不是什么新技术,Java,Ruby等都用到了。

这里主要讲Python对象的引用计数

PyObject中的ob_refcnt

Python中,创建一个PyObject时会初始化引用计数为1。

object.h,宏定义了初始化ob_refcnt的方法

#define Py_REFCNT(ob)           (((PyObject*)(ob))->ob_refcnt)


/* Without Py_TRACE_REFS, there's little enough to do that we expand code
 * inline.
 */
#define _Py_NewReference(op) (                          \
    _Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA         \
    _Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA               \
    Py_REFCNT(op) = 1)

而当外部的指针指向这个对象时候,需要通过外部调用来管理,借助Py_INCREFPy_DECREF来实现引用计数的增减。

在CPython的虚拟机中,当有新的指针指向PyObject时,引用计数就加一,当指针移走时,引用计数减一,如果一个对象的引用计数变为0,那这个对象将被销毁。

这一检查放在Py_DECREF宏定义中完成,其中的if语句判断,如果ob_refcnt == 0,则调用_Py_Dealloc(),销毁对象。

#define Py_DECREF(op)                                   \
    do {                                                \
        PyObject *_py_decref_tmp = (PyObject *)(op);    \
        if (_Py_DEC_REFTOTAL  _Py_REF_DEBUG_COMMA       \
        --(_py_decref_tmp)->ob_refcnt != 0)             \
            _Py_CHECK_REFCNT(_py_decref_tmp)            \
        else                                            \
            _Py_Dealloc(_py_decref_tmp);                \
    } while (0)

results matching ""

    No results matching ""