Brief introduction
Python's memory management is implemented through the object's reference counter, the object's creation will be the reference counter plus 1, the reference counter will add 1, and vice versa, the reference counter will be reduced by 1, when the Python object reference counter is 0, The object will be recycled and released.
This kind of memory management is a certain disadvantage, one is that it needs extra space to maintain the reference count, the second is that it can not solve the object "circular reference" problem, so there are many languages such as Java did not use the algorithm to garbage recycling mechanism.
Python Code Instance
import sysdef test_refcount(a): print("func a refcount: {}".format(sys.getrefcount(a)))if __name__ == ‘__main__‘: // 直接创建Python对象 a = 189987319 print("a refcount: {}".format(sys.getrefcount(a))) // 调用一次Python对象a,则引用计数器加1 b = a print("b, a refcount: {}".format(sys.getrefcount(a))) // 存入列表,字段,或者元组中,引用计数器都会加1 c = [a] print("c, a refcount: {}".format(sys.getrefcount(a))) // 使用函数调用的时候,传参的时候引用计数器加1,调用的时候引用计数器也会加1,因此是加2 test_refcount(a)结果:a refcount: 1b, a refcount: 2c, a refcount: 3func a refcount: 5
Python objects are managed and freed in the C API
void Py_incref (Pyobject *o) Python object reference counter plus 1, the object cannot be null, or an error will be
void Py_xincref (Pyobject *o) Python object reference counter plus 1, the object can be null, but the reference counter does not take effect
void Py_decref (Pyobject *o) Python object has a reference counter minus 1, the object cannot be null, or an error will be
void Py_xdecref (Pyobject *o) Python object reference counter minus 1, the object can be null, but the reference counter does not take effect
void Py_clear (Pyobject *o) Direct Python application counter clear 0
C code example
Header file
//// Created by lanyulei on 18-9-9.//#ifndef PRINT_DEMO1_PYREFCOUNT_H#define PRINT_DEMO1_PYREFCOUNT_H#include <stdio.h>#include <stdlib.h>#include <string.h>#include <Python.h>void pyRefCount();#endif //PRINT_DEMO1_PYREFCOUNT_H
source file
//// Created by lanyulei on 18-9-9.//#include "pyRefCount.h"// Python对象的保留及释放void pyRefCount(){ PyObject* py_ival = Py_BuildValue("i", 56486); // 创建对象 printf("Py_BuildValue: py_ival refcount: %ld\n", Py_REFCNT(py_ival)); // 打印Python对象的引用计数器 Py_XINCREF(py_ival); // Python对象的引用计数器加1 printf("Py_BuildValue: py_ival refcount: %ld\n", Py_REFCNT(py_ival)); // 打印Python对象的引用计数器 Py_XDECREF(py_ival); // Python对象的引用计数器减1 printf("Py_BuildValue: py_ival refcount: %ld\n", Py_REFCNT(py_ival)); // 打印Python对象的引用计数器 Py_CLEAR(py_ival); // Python对象的引用计数器清0 printf("Py_BuildValue: py_ival refcount: %ld\n", Py_REFCNT(py_ival)); // 打印Python对象的引用计数器}
Main.cpp
#include "pyRefCount.h"int main() { // 初始化Python虚拟机 Py_Initialize(); // 判断Python虚拟机是否成功 if (Py_IsInitialized() == 0){ printf("fal to initialize Python\n"); return -1; } printf("server start\n"); pyRefCount(); // 退出Python虚拟机 Py_Finalize(); return 0;}
Python C API Reference counter (iii)