从Python的源码来解析Python下的freeblock
作者:oyjh1986 时间:2023-07-26 20:44:39
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
0
投稿
猜你喜欢
Python imageio读取视频并进行编解码详解
2021-02-20 07:32:53
在pytorch中如何查看模型model参数parameters
2021-12-04 22:43:29
Python生成器以及应用实例解析
2021-07-06 21:45:40
python 将对象设置为可迭代的两种实现方法
2023-08-24 18:01:39
MySQL的WHERE语句中BETWEEN与IN的使用教程
2024-01-28 22:37:31
asp 横排显示数据
2011-03-10 10:50:00
python中必要的名词解释
2023-10-17 23:30:32
mysql数据表的基本操作之表结构操作,字段操作实例分析
2024-01-17 18:15:54
bak文件怎么打开 2000w数据怎么打开?
2024-01-12 19:30:43
java连接mysql数据库详细步骤解析
2024-01-19 15:55:25
Python入门教程(四十)Python的NumPy数组创建
2023-11-14 08:36:32
asp任何取得多个表单的值
2008-04-15 15:31:00
Python生产者与消费者模型中的优势介绍
2023-06-18 01:21:17
Goland 的安装及激活教程(window、linux下安装)
2024-05-08 10:51:51
Python上下文管理器深入讲解
2022-02-23 08:50:02
利用XSLT把ADO记录集转换成XML
2008-09-05 17:12:00
Python3使用 GitLab API 进行批量合并分支
2023-05-26 08:38:53
asp select下拉菜单选择图标并实时显示
2011-04-03 10:33:00
解决python3.x安装numpy成功但import出错的问题
2023-12-29 22:33:44
Oracle数据库集复制方法浅议
2010-07-21 12:50:00