对象销毁_CPython源码阅读7-对象的销毁-空闲对象缓冲池

上篇文章CPython源码阅读-基础6 说到最简单的对象浮点对象的创建,我们可以感觉到,这种对象创建和销毁应该是非常频繁的。如果每次创建都申请内存空间,每次销毁都回收内存空间的话,那Python的效率应该会更低的。CPython内部目前的做法是,在操作系统之上,封装一个空闲对象内存缓冲池。

具体的做法是,Python在浮点对象销毁后,不是直接将内存回收,而是将要销毁的空间浮点对象放入一个空闲链表。后续需要创建浮点对象时,直接在空闲链表中取,提高效率,不用每次都分配内存。新的浮点数对象,从新初始化对应成员即可。Python中其他对象也有对应的空闲对象缓冲池。

45100c8f3a3a282de2c1f145854759eb.png

空闲对象内存缓冲池

# define PyFloat_MAXFREELIST 100

//要销毁的浮点对象放入空闲对象缓冲池的最大个数

struct _Py_float_state {

/* Special free list

free_list is a singly-linked list of available PyFloatObjects,

linked via abuse of their ob_type members. */

int numfree;

//当前空闲对象缓冲池已经存在的浮点对象的数量

PyFloatObject *free_list;

//指向链表头结点的指针

};

这个内存池中的链表的通过内部的ob_type指针指向下一个对象的。

3ced66057be334c5559cf5dfb4ceb854.png

内存池中链表的链接关系

回过头再看,PyFloat_FromDouble,就是从内存池拿东西。

cpython-masterObjectsfloatobject.c

PyObject *

PyFloat_FromDouble(double fval)

{

struct _Py_float_state *state = get_float_state();

PyFloatObject *op = state->free_list;

if (op != NULL) {

#ifdef Py_DEBUG

// PyFloat_FromDouble() must not be called after _PyFloat_Fini()

assert(state->numfree != -1);

#endif

state->free_list = (PyFloatObject *) Py_TYPE(op);

state->numfree--;

}

else {

op = PyObject_Malloc(sizeof(PyFloatObject));

if (!op) {

return PyErr_NoMemory();

}

}

_PyObject_Init((PyObject*)op, &PyFloat_Type);

op->ob_fval = fval;

return (PyObject *) op;

}

float_dealloc 就是把空闲待销毁的对象放入内存池。

static void

float_dealloc(PyFloatObject *op)

{

if (PyFloat_CheckExact(op)) {

struct _Py_float_state *state = get_float_state();

#ifdef Py_DEBUG

// float_dealloc() must not be called after _PyFloat_Fini()

assert(state->numfree != -1);

#endif

if (state->numfree >= PyFloat_MAXFREELIST) {

PyObject_FREE(op);

return;

}

state->numfree++;

Py_SET_TYPE(op, (PyTypeObject *)state->free_list);

state->free_list = op;

}

else {

Py_TYPE(op)->tp_free((PyObject *)op);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值