自定义内存池
内存池是预先分配一大块内存,然后从中按需分配小块的技术。内存池减少了 malloc/free 的调用次数,避免堆碎片,提高分配速度,特别适合频繁分配释放小对象的场景。
简单内存池
#define POOL_SIZE (1024 * 1024) /* 1MB */
struct Pool {
char memory[POOL_SIZE];
size_t offset;
};
void pool_init(struct Pool *pool)
{
pool->offset = 0;
}
void *pool_alloc(struct Pool *pool, size_t size)
{
/* 对齐到 8 字节 */
size = (size + 7) & ~7;
if (pool->offset + size > POOL_SIZE)
return NULL;
void *p = pool->memory + pool->offset;
pool->offset += size;
return p;
}
void pool_reset(struct Pool *pool)
{
pool->offset = 0;
}
使用示例
struct Pool pool;
pool_init(&pool);
/* 分配多个对象 */
int *arr = pool_alloc(&pool, 100 * sizeof(int));
struct Node *node = pool_alloc(&pool, sizeof(struct Node));
char *str = pool_alloc(&pool, 256);
/* 使用 */
/* ... */
/* 一次性释放所有 */
pool_reset(&pool);
固定大小内存池
#define BLOCK_SIZE 64
#define BLOCK_COUNT 1000
struct FixedPool {
char memory[BLOCK_COUNT][BLOCK_SIZE];
int free_list[BLOCK_COUNT];
int free_count;
};
void fixed_pool_init(struct FixedPool *pool)
{
pool->free_count = BLOCK_COUNT;
for (int i = 0; i < BLOCK_COUNT; i++)
pool->free_list[i] = i;
}
void *fixed_pool_alloc(struct FixedPool *pool)
{
if (pool->free_count == 0)
return NULL;
int index = pool->free_list[--pool->free_count];
return pool->memory[index];
}
void fixed_pool_free(struct FixedPool *pool, void *p)
{
int index = ((char *)p - (char *)pool->memory) / BLOCK_SIZE;
pool->free_list[pool->free_count++] = index;
}
最佳实践
- 同生命周期对象用简单内存池
- 固定大小对象用固定内存池
- 对齐分配地址(通常 8 字节)
- 内存池不替代所有分配,只优化热点
- 注意内存池的线程安全