内存池与数据结构
Nginx 自研内存池与数据结构体系,避免频繁 malloc/free,提升高并发场景下的内存管理效率。
内存池机制
内存池结构
C
typedef struct {
u_char *last; // 当前 block 已分配位置
u_char *end; // 当前 block 结束位置
ngx_pool_t *next; // 下一个内存池
ngx_uint_t failed; // 分配失败次数
// ...
} ngx_pool_t;
核心操作
C
// 创建内存池
ngx_pool_t *pool = ngx_create_pool(1024, log);
// 分配内存(自动清零)
void *p = ngx_pcalloc(pool, sizeof(ngx_http_conf_ctx_t));
// 分配内存(不清零)
void *p = ngx_palloc(pool, size);
// 分配大块内存(直接从系统分配)
void *p = ngx_pnalloc(pool, size);
// 销毁内存池
ngx_destroy_pool(pool);
// 重置内存池(不销毁,可复用)
ngx_reset_pool(pool);
小对象在池内分配,超过 pool->max 阈值直接从系统分配,避免池碎片化。
内存池清理回调
C
ngx_pool_cleanup_t *c;
c = ngx_pool_cleanup_add(pool, sizeof(my_cleanup_data_t));
c->handler = my_cleanup_handler;
c->data = my_data;
核心数据结构
动态数组(ngx_array_t)
C
// 创建数组
ngx_array_t *arr = ngx_array_create(pool, 10, sizeof(ngx_str_t));
// 添加元素
ngx_str_t *s = ngx_array_push(arr);
ngx_str_set(s, "hello");
// 批量添加
ngx_str_t *s = ngx_array_push_n(arr, 3);
s[0] = ...; s[1] = ...; s[2] = ...;
// 销毁
ngx_array_destroy(arr);
链表(ngx_list_t)
C
// 创建链表
ngx_list_t *list = ngx_list_create(pool, 4, sizeof(ngx_str_t));
// 添加元素
ngx_str_t *s = ngx_list_push(list);
ngx_str_set(s, "item");
// 遍历链表
ngx_list_part_t *part = &list->part;
ngx_str_t *data = part->elts;
for (i = 0; /* void */; i++) {
if (i >= part->nelts) {
if (part->next == NULL) break;
part = part->next;
data = part->elts;
i = 0;
}
// 处理 data[i]
}
队列(ngx_queue_t)
C
ngx_queue_t q;
ngx_queue_init(&q);
// 插入
ngx_queue_insert_head(&q, &item->queue);
ngx_queue_insert_tail(&q, &item->queue);
// 移除
ngx_queue_remove(&item->queue);
// 遍历
ngx_queue_t *q;
for (q = ngx_queue_head(&sentinel);
q != ngx_queue_sentinel(&sentinel);
q = ngx_queue_next(q)) {
my_item_t *item = ngx_queue_data(q, my_item_t, queue);
}
ngx_queue_t 是嵌入式队列,不分配内存,只需结构体内包含
ngx_queue_t字段。
哈希表(ngx_hash_t)
C
// 初始化
ngx_hash_init_t hash;
hash.max_size = 1024;
hash.bucket_size = ngx_cacheline_size;
hash.name = "my_hash";
hash.pool = pool;
hash.temp_pool = temp_pool;
ngx_hash_keys_arrays_t ha;
ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts);
// 查找
value = ngx_hash_find(&hash, key_hash, key.data, key.len);
红黑树(ngx_rbtree_t)
C
ngx_rbtree_t tree;
ngx_rbtree_node_t sentinel;
ngx_rbtree_init(&tree, &sentinel, ngx_rbtree_insert_timer_value);
// 插入
ngx_rbtree_insert(&tree, &node);
// 删除
ngx_rbtree_delete(&tree, &node);
数据结构使用场景
| 结构 | 场景 |
|---|---|
| ngx_array_t | 配置指令数组、upstream 列表 |
| ngx_list_t | 请求头/响应头 |
| ngx_queue_t | 定时器、连接管理 |
| ngx_hash_t | 变量查找、location 匹配 |
| ngx_rbtree_t | 定时器、缓存管理 |
要点总结
- 内存池通过
ngx_create_pool创建,ngx_pcalloc/ngx_palloc分配,ngx_destroy_pool销毁 - 小对象在池内分配,大对象直接系统分配,避免池碎片化
ngx_array_t适合顺序访问,ngx_list_t适合动态增长场景ngx_queue_t是嵌入式双向链表,不分配额外内存ngx_hash_t用于快速查找,ngx_rbtree_t用于有序数据管理
📝 发现内容有误?点击此处直接编辑