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。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!