关于内存池 pool 的操作已经大致比较清楚了。简而言之就是以 pool 为单位,管理了一系列连续的 block。比 pool 更高一级的是 arena,是 pool 的集合。arena 的结构看起来这样:
arena 的结构与 pool 有很多相似的地方,但是最大的区别在于 arena 结构与实际内存是分开的,而非像 pool 一样头部与内存连续分配。其中:
- address 是通过 malloc 分配的大块内存起始位置。
- pool_address 是 arena 中未使用内存池的位置,这个位置会随着 pool 的消耗而移动。需要特别注意的是, arena 的第一个 pool 会对齐到内存分页,代码如下:
arenaobj->pool_address = (block*)arenaobj->address; arenaobj->nfreepools = MAX_POOLS_IN_ARENA; //计算对齐位置 excess = (uint)(arenaobj->address & POOL_SIZE_MASK); if (excess != 0) { //浪费一个 pool --arenaobj->nfreepools; // 对齐到分页 arenaobj->pool_address += POOL_SIZE - excess; }
- freepools 则作为 pool 的缓存,当一个 pool 所有的 block 都闲置的时候,这个 pool 会被链入 freepools 链表。图中这个链表是以虚线绘制,是因为这些 pools 实际上都是在 address 指向的连续内存中的一部分,只不过它们之间存在关联。
- 最后两个指针则用于将 arena 链接在一起,分别构成 used 和 usable arena 链表。