python | 引用计数器
source link: https://benpaodewoniu.github.io/2022/12/29/python184/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
python
的内存管理机制是引用计数器为主,标记清除和分代回收为辅 + 缓存机制。
环状双向链表 refchain
在 python
中创建的任何一个对象都会放在 refchain
中。
当创建一个对象,比如
name = "123"
会同时创建
- 上一个对象
- 下一个对象
当然,根据类型的不同,具体的存储也有一点不同,比如,对于 数组来说,会增加
- items 属性
对于 int
或者其他来说,会增加
value
属性
C 语言源码
#define PyObject_HEAD PyObject ob_base;
#define PyObject_VAR_HEAD PyVarObject ob_base;
// 宏定义,包含 上一个、下一个,用于构造双向链表
#define _PyObject_HEAD_EXTRA
struct _object *_ob_next;
struct _object *_ob_prev;
typedef struct _object{
_PyObject_HEAD_EXTRA // 用于构造双向链表
Py_ssize_t ob_refcnt; // 引用计数器
struct _typeobject *ob_type; // 数据类型
}PyObject;
typedef struct{
PyObject ob_base; //PyObject 对象
Py_ssize_t ob_size; // 元素个数
}PyVarObject;
对于不同的类型,会创建不同的结构体
float 类型
typedef struct{
PyObject_HEAD
double ob_fval;
}PyFloatObject;
data = 3.14
会创建_ob_next = refchain
下一个对象_ob_prev = refchain
上一个对象ob_refcnt = 1
ob_type = float
ob_fval = 3.14
其他类型会有自己的结构体。
当 python
程序运行时,会根据数据类型的不同找到其对应的结构体,根据结构体的字段来进行创建相关的数据,然后将对象添加到 refchain
双向链表中。
在 C
源码中有两个关键结构体
- PyObject
- PyVarObject
引用计数器
对象中的 ob_refcnt
就是引用计数器,值默认为 1
。当有其他变量引用的时候,引用计数器会发生变化。
a = 999 # ob_refcnt = 1
b = a # ob_refcnt = 2
del a # ob_refcnt = 1
当引用计数器为 0
时,无对象使用,则会进行垃圾回收。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK