关键数据结构
对照上图,我们看一下相关数据结构
PooledArena
代表内存中一块连续区域,其内部有2个重要的数据结构
-
tinySubpagePools/smallSubpagePools
小于8KB的内存申请,优先从tinySubpagePools/smallSubpagePools数组中申请内存。
如果subPages数组为空,则从PoolChunk申请内存。
-
PoolChunkList
PooledArena按内存使用率的不同,将PoolChunk分成了6个List。
比如q025这个PoolChunkList里面的PoolChunk的内存使用率都在25%(不一定很精确)
PoolChunk
负责管理一块16MB的内存区域
-
以下两种场景,直接从PoolChunk中申请内存
- 申请内存大于8KB小于16MB时
- 申请内存小于8KB,但是tinySubpagePools/smallSubpagePools为空时
-
PoolChunk的选择策略
优先从内存使用率小的PoolChunkList中,挑选PoolChunk进行内存分配。
-
监控PoolChunk的内存使用率
比如:线程从内存使用率50%的PoolChunkList挑选了一个PoolChunk
分配内存后PoolChunk的内存使用率超过了75%
则将此PoolChunk迁移到内存使用率为75%的PoolChunkList中
-
PoolSubpage
负责管理从PoolChunk申请的小于8KB的内存区域
内存分配的套路
-
我们可以将PoolChunk看成”内存生产商“,有2条产品线
tiny/small :负责生成8KB以内的内存
normal:负责生产8KB到16MB之间固定容量的内存(16MB,8MB,4MB,2MB……16KB,8KB)
-
将tinySubpagePools/smallSubpagePools 看成“二手寄卖商店”,负责售卖小于8KB的内存
- tinySubpagePools负责售卖小于512Byte的内存
- smallSubpagePools负责售卖大于512Byte小于等于8KB的内存
将线程看成购买内存的客户,买tiny/small产品的是小客户,买normal产品的是大客户
大客户比较有钱,不会购买8KB一下的内存,我们主要关注一下小客户的艰辛
由于PoolChunk厂商最小规格的内存是8KB,如果小客户要买1KB的内存,会优先在“二手寄卖商店”购买
如果商店没货,则在PoolChunk厂商购买8KB内存,然后将剩余的7KB内存挂在“二手寄卖商店”