首页建站经验 从Python的源码来解析Python下的freeblock

从Python的源码来解析Python下的freeblock

1 引言在python内存管理中,有一个block的概念。它比较类似于SGI次级空间配置器。首先申请一块大的空间(4KB),然后把它切割成一小份(8, 16 一直到512)。当有内存申请的请求时候,简…

1 引言

在python内存管理中,有一个block的概念。它比较类似于SGI次级空间配置器。

首先申请一块大的空间(4KB),然后把它切割成一小份(8, 16 一直到512)。

当有内存申请的请求时候,简单的流程是:根据大小找到对应的block,然后在freeblock 上给它一份。

2 问题

整个过程是一种比较自然的slab分配方式。但当我读到这段代码时,却感到疑惑:

static void* _PyObject_Malloc(void* ctx, size_t nbytes)

{

...

pool->freeblock = (block*)pool + pool->nextoffset;

pool->nextoffset += INDEX2SIZE(size);

*(block **)(pool->freeblock) = NULL; // [1]

...

}

freeblock指向空闲的链表,为它赋值很好理解。但是为什么要加上代码1处那一句!

对C比较熟悉的童鞋很容易能看出它的作用,它在为*freeblock赋值为NULL。

但是为什么要这么做?

直到看到内存回收的代码:

static void _PyObject_Free(void* ctx, void*p)

{

...

*(block**)p = lastfree = pool->freeblock;

pool->freeblock = (block*)p;

...

}

回想一下SGI次级空间配置,它需要一个链表,指向block中可用的小块。因为这些快,是离散的,只有用指针才能索引它。

在SGI次级空间配置中,是用一个union,达到了节省空间的目的:有数据时,它存储着真正的数据;没有数据时,它就变成指向下一块可用内存的指针:

union __Obj {

union __Obj* free_list_link;

char client_data[];

};

这样一想,问题就变得很明显了。freeblock指向一个链表,链表的next域就由它自己来索引。

在_PyObject_Free中,内存p是要被回收的,它应该插在freeblock的链表头,freeblock被更新指向它。同时,p指向原来freeblock指向的内容,这是一个很简单的链表插入操作。

这样在遍历的时候,我们就可以用freeblock = * freeblock的方式来工作了。

如下图所示:

python

 

本文来自网络,不代表1号站长-站长学院|资讯交流平台立场。转载请注明出处: https://www.1cn.cc/jianzhan/jingyan/16659.html
上一篇WordPress实现搜索结果包括自定义文章类型内容的方法
下一篇 javascript中基本类型和引用类型的区别分析
admin

作者: admin

这里可以再内容模板定义一些文字和说明,也可以调用对应作者的简介!或者做一些网站的描述之类的文字或者HTML!

为您推荐

评论列表()

    联系我们

    联系我们

    0898-88888888

    在线咨询: QQ交谈

    邮箱: email@wangzhan.com

    工作时间:周一至周五,9:00-17:30,节假日休息

    关注微信
    微信扫一扫关注我们

    微信扫一扫关注我们

    关注微博
    返回顶部