(Python学习2)整数对象

来源:互联网 发布:ubuntu的root默认密码 编辑:程序博客网 时间:2024/04/30 13:40

整数类型比较简单,定义如下(Python2.x中,在Python3.x中int与long合并)

typedef struct {    PyObject_HEAD    long ob_ival;} PyIntObject;

整数在程序执行过程中创建销毁特别频繁,Python使用整数对象池(几乎所有对象都是)来避免内存的频繁申请释放。

分为小整数对象池、通用整数对象池。

1、整数对象池基础结构

#define BLOCK_SIZE  1000      // 内存块的大小#define BHEAD_SIZE  8         // 容纳64位指针#define N_INTOBJECTS    ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))   // 容纳整数对象的个数typedef struct _intblock {    struct _intblock *next;    PyIntObject objects[N_INTOBJECTS];}PyIntBlock; static PyIntBlock *block_list = NULL;static PyIntObject *free_list = NULL;
如图所示,objects实质为N个整数对象的数组。

block_list通过单向列表维护整个对象池,free_list通过单向列表维护所有未使用内存。


2、通用整数对象池

创建通用整数对象池时,会使得objects中每个整数对象的ob_type指向前一个整数对象,从而形成单向列表。

在freelist指向的地方创建一个整数对象,然后free_list指向下一个空闲空间。当一个整数对象的引用计数为0时,该对象的ob_type指向freelist所指空间,然后freelist指向该处,从而模拟出该对象已被删除。

static void int_dealloc(PyIntObject *v){    if (PyInt_CheckExact(v)) {        v->ob_type = (struct _typeobject *)free_list;        free_list = v;    }    else        v->ob_type->tp_free((PyObject *)v);}

多次创建删除后,对象的ob_types是跨PyIntBlock的,从而freelist也可在多个PyIntBlock之间来回跳动,不会出现内存泄漏等情况。

3、小整数对象池

小整数对象池保存了[-5, 100)之间的整数对象,在python开始运行时初始化,指针按照顺序存放于small_ints[]中。

#define NSMALLPOSINTS       100#define NSMALLNEGINTS       5static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];

整体结构如下图所示

-----------------------------------------------------------------------------------------------------------------

运行时,先查看是否在小对象池中,有则直接使用;无则在通用对象池中新建。

小对象池中整数对象是唯一的,即 a=5 与 b=5 指向同一对象。

大对象池中整数对象不一定,a=1234 与 b=1234不一定指向同一对象,与创建方式有关。

原创粉丝点击