Python进阶编程:编写更高效、优雅的Python代码
上QQ阅读APP看书,第一时间看更新

0.3.10 引用计数

Python通过引用计数来管理对象。

Python中的每个变量都是一个对象,都有ob_refcnt变量。该变量用于维护对象的引用计数,并根据引用计数的值决定对象的创建与销毁。

Python中主要通过Py_INCREF(op)与Py_DECREF(op)这两个宏来增加和减少对于对象的引用计数。

当一个对象的引用计数减少到0时,Py_DECREF将调用该对象的tp_dealloc来释放对象所占用的内存和系统资源。但这并不意味着最终一定会调用释放的内存空间。由于频繁的申请、释放内存会大大降低Python的执行效率,因此Python中大量采用了内存对象池技术,使得对象释放的空间归还给内存池而不是直接释放,后续使用可先从对象池中获取。

相关源码如下:


// Include/object.h
#define _Py_NewReference(op) (                          \
    _Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA         \
    _Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA               \
    Py_REFCNT(op) = 1)

#define Py_INCREF(op) (                         \
    _Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA       \
    ((PyObject *)(op))->ob_refcnt++)

#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)