接上文:

2.1  arean

多个pool聚合起来就是arean了,当然它也有默认的大小,一般是256k,包含的poo的个数就是256 / 4 = 64 个

先看下arean:

struct arena_object {

uptr address;

        block* pool_address;

uint nfreepools;

       uint ntotalpools;

struct pool_header* freepools;

struct arena_object* nextarena;

struct arena_object* prevarena;

};

在概念上其实就是一个结构体:

未使用的arena:arean_object构成的集合会成为一个数组,数组的首地址有arean来维护,这个数组就是py中

通用小块内存的内存池,另一方面nextarea和prearea是用来连接arean_object来形成链表结构的,arena用来

管理一组pool,

与pool管理block是类似的,不同的是,pool_header管理的内存是和pool_header连接在一起

areana_object和它管理的内存却是分离的,当pool_header被申请时,它所管理的内存block集合也会一起

被申请,而areana_object被申请时,pool集合的内存却没有被申请,也就是在某一时刻,pool和sreana才

会建立联系,arean从未使用状态变为可用状态,可用状态和不可用状态分别维护自己的arena链表,未使用

状态的链表是单向链表,可用状态的链表是一个双向链表,使用new_arena来申请,这就是那个arena

完整的pool包含pool_header和blocks,arena也包含 arena_object和arena_object所包含的

pool集合,在创建新的arena时,py会先检查是否还有未使用状态的arena,如果有,从中抽取一个,把申请

的内存地址赋值给arena的address,申请到的这256k的内存大小就是pool的容身之处,,这是arena就

和pool建立了联系,脱离了未使用态,py还对申请到的256k的内存大小做了处理,使其是边界对齐的,把pool

集合交给pool_address来管理,实际上所有arena的集合就是小块内存池,但py操作内存的最小单元却是pool

一个arena中的pull总是处于下边三种状态中的一种:

1)used状态:至少有一个pool处于使用状态,至少一个pool处于未使用状态,内部维护了一个usedpool数组

2)full状态:pool中所有的block都已经被使用完毕

3)empty状态:pool中所有的block都未被使用,处于这个状态的pool的集合通过pool_header中的next_pool构成一个链表,这个链表的表头就是arena_object中的freepools

注意:full状态的pool是相互独立的,并没有形成链表


2.2  缓冲池

PyObject_Malloc会在内存池中申请内存,当申请的内存大于256k时,PyObject_Malloc会变成真正的malloc,当然,可以通过修改python的源码来修改这个默认值

2.2.1 pool的初始化

      在python启动的时候,usedpools这个小块空间内存池并不存在可用内存,py采用了延迟分配的策略,申请内存时才建立这个内存池,例如申请28字节的内存大小,py会先在usedpools对应位置查找,查找不到任何可用的pool时,py会从unused_arenas中的第一个可用arena获取一个pool,而如果此时usable_arenas为空的话,py会新申请一个arena

PS: 写的比较简略,希望有兴趣的读者去看下Python源码剖析这本书,pdf版,you can get :

哈哈~  希望可以帮到大家