python-内存管理

python对大于512字节的对象会使用malloc动态申请内存,对于小于512字节的对象使用内存池。
内存池分三个等级block、pool和arena。

block

block是一个8字节为步长的大小固定的内存块,总共64种block,从小到大依次是8字节,16字节、24字节、32字节直到512字节。

图片来源:古明地觉的公众号

在分配内存时也是以内存块为基准,只包含内部碎片。比如说需要5字节内存,分配一个8字节的内存块,需要10字节分配一个16字节的内存块。

pool

一组block集合称为一个pool,一个pool管理着一堆具有固定大小的内存块,一个pool的大小通常为一个系统内存页,即4kb。
pool内部每一个的block大小相同,pool间可能不同也可能相同。

class Pool:
    count: int # 已分配块数
    sizeidx: int  # block种类id,0表示8字节,1表示16字节,2表示24字节
    freeblock: block  # 第一个可用块地址
    nextoffset: block  # 下一个可用块地址,即第二个可用块地址
    maxnextoffset: block # 最后一个可用块地址
    nextpool:pool
    prevpool:pool
    arenaidx:int

arena

pool的集合就是arena,arena的大小是256kb,python一开始默认申请16个arena。一个arena有64个pool,pool之间会形成一个链表。而arean之间组成的是一个数组。

class Arean:
    pool_address: pool  # 下一个被划分的pool,pool只有在被使用的适合才会决定其内部block大小
    nfreepools: int  # 可用pool数量
    ntotalpools: int # arean中所有pool的数量
    feepools: pool  # 第一个可用pool
    nextarean:arean
    prevarena:arena

arena是通过数组进行组织起来的,这个数组(areans)就是内存池,arena又分为可用和未使用的arean,未使用的arena通过单向链表组织起来,可用的arena通过双向链表组织。

pool中block的集合是一段连续内存,pool申请时,block也申请了。但是arean中的pool集合并不是连续内存。

python在申请内存时基本的操作单元是pool而不是arena。

管理同类型的pool之间会组成一个双向链表,所以used状态的pool有64条双向链表。这 64 条双向链表会放在一个名为 usedpools 的数组中。
在申请内存时,会优先从最满的arena的最满的pool中找到第一个合适的block返回。
当一个pool所有的block都用完的会从usedpools的相应链表中移除,当有一个block被释放时,pool会被插入到头结点,以保证优先从最满 的pool里寻找block。

posted @   店里最会撒谎白玉汤  阅读(424)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示