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


Posted in Python onMay 11, 2015

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的源码来解析Python下的freeblock

Python 相关文章推荐
Python中random模块生成随机数详解
Mar 10 Python
Python下调用Linux的Shell命令的方法
Jun 12 Python
python pcm音频添加头转成Wav格式文件的方法
Jan 09 Python
python如何实现数据的线性拟合
Jul 19 Python
python使用beautifulsoup4爬取酷狗音乐代码实例
Dec 04 Python
Python交互环境下打印和输入函数的实例内容
Feb 16 Python
记一次pyinstaller打包pygame项目为exe的过程(带图片)
Mar 02 Python
Python3实现打印任意宽度的菱形代码
Apr 12 Python
python 操作mysql数据中fetchone()和fetchall()方式
May 15 Python
Python LMDB库的使用示例
Feb 14 Python
2021年最新用于图像处理的Python库总结
Jun 15 Python
Anaconda安装pytorch和paddle的方法步骤
Apr 03 Python
详解Python的Django框架中的templates设置
May 11 #Python
Python素数检测的方法
May 11 #Python
Python中IPYTHON入门实例
May 11 #Python
Python使用MONGODB入门实例
May 11 #Python
python学习数据结构实例代码
May 11 #Python
Python使用CMD模块更优雅的运行脚本
May 11 #Python
Python中DJANGO简单测试实例
May 11 #Python
You might like
PHP取整数函数常用的四种方法小结
2012/07/05 PHP
解决nginx不支持thinkphp中pathinfo的问题
2015/07/21 PHP
超强多功能php绿色集成环境详解
2017/01/25 PHP
PHP htmlspecialchars() 函数实例代码及用法大全
2018/09/18 PHP
广告切换效果(缓动切换)
2009/05/27 Javascript
JavaScript 对Cookie 操作的封装小结
2009/12/31 Javascript
jQuery实现的向下图文信息滚动效果
2015/05/03 Javascript
教你JS中的运算符乘方、开方及变量格式转换
2016/08/09 Javascript
JS实现动态给标签控件添加事件的方法示例
2017/05/13 Javascript
JavaScript之underscore_动力节点Java学院整理
2017/07/03 Javascript
解决html-jquery/js引用外部图片时遇到看不了或出现403的问题
2017/09/22 jQuery
layer.prompt输入层的例子
2019/09/24 Javascript
在vue中created、mounted等方法使用小结
2020/07/21 Javascript
[02:37]2018DOTA2亚洲邀请赛赛前采访 VP.no[o]ne心中最强SOLO是谁
2018/04/04 DOTA
[50:05]VGJ.S vs OG 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
详解Django中的权限和组以及消息
2015/07/23 Python
Python进阶篇之字典操作总结
2016/11/16 Python
Python 查看文件的编码格式方法
2017/12/21 Python
在python 中实现运行多条shell命令
2019/01/07 Python
Python读写文件模式和文件对象方法实例详解
2019/09/17 Python
Django 实现xadmin后台菜单改为中文
2019/11/15 Python
python 生成任意形状的凸包图代码
2020/04/16 Python
使用AJAX和Django获取数据的方法实例
2020/10/25 Python
利用CSS的Sass预处理器(框架)来制作居中效果
2016/03/10 HTML / CSS
html5的localstorage详解
2017/05/09 HTML / CSS
详解基于 Canvas 手撸一个六边形能力图
2019/09/02 HTML / CSS
文明之星事迹材料
2014/05/09 职场文书
机械专业求职信
2014/05/25 职场文书
房屋鉴定委托书范本
2014/09/23 职场文书
先进班集体事迹材料
2014/12/25 职场文书
2015年英语教研组工作总结
2015/05/23 职场文书
大学生见习总结报告
2015/06/24 职场文书
重阳节座谈会主持词
2015/07/03 职场文书
小学六年级班主任工作经验交流材料
2015/11/02 职场文书
小学生节约用水倡议书
2019/08/12 职场文书
90后经典动画片排行:《数码宝贝》第二,《小鲤鱼历险记》在榜
2022/03/18 日漫