本篇首先把 内存池结构 大概的说一下,具体使用将在下一节细致描述
首先知道内存池的作用
为什么需要内存池?
a. 在大量的小块内存的申请和释放的时候,能更快地进行内存分配(对比malloc和free)
b.减少内存碎片,防止内存泄露。
内存池的原理
内存池的原理非常简单,用申请一块较大的内存来代替N多的小内存块,当有需要malloc一块
比较小的内存是,直接拿这块大的内存中的地址来用即可。
当然,这样处理的缺点也是很明显的,申请一块大的内存必然会导致内存空间的浪费,但是
比起频繁地malloc和free,这样做的代价是非常小的,这是典型的以空间换时间。
Ngnix的内存池使用的数据结构是链表。
首先
typedef struct ngx_pool_s ngx_pool_t;
我们知道以上定义 其结构体是什么样的呢?
struct ngx_pool_s {
u_char *last;
u_char *end;
ngx_pool_t *current;
ngx_chain_t *chain;
ngx_pool_t *next;
ngx_pool_large_t *large;
ngx_pool_cleanup_t *cleanup;
ngx_log_t *log;
};
以上是0。5版本的,1.0版本有些改变
struct ngx_pool_s {
ngx_pool_data_t d;//表示数据区域
size_t max;//内存池能容纳数据的大小
ngx_pool_t * current;//当前内存池块(nginx中的内存池是又一连串的内存池链表组成的)
ngx_chain_t* chain;//主要为了将内存池连接起来
ngx_pool_large_t* large;//大块的数据
ngx_pool_cleanup_t* cleanup;//清理函数
ngx_log_t* log;//写log
};
typedef struct {
u_char *last;
u_char *end;
ngx_pool_t *next;
ngx_uint_t failed;
} ngx_pool_data_t;
但是原理是一样的,他把两个地址进行封装了struct
看了这个结构,我们想知道这个结构到底是什么样的,他的每个数据字段什么用呢?
再把其他的数据结构贴上来。
typedef struct ngx_chain_s ngx_chain_t;
struct ngx_chain_s {
ngx_buf_t *buf;
ngx_chain_t *next;
};
这个一个 内存池的链表
而其中的
typedef struct ngx_buf_s ngx_buf_t;
struct ngx_buf_s { u_char *pos; u_char *last; off_t file_pos; off_t file_last; u_char *start; /* start of buffer */ u_char *end; /* end of buffer */ ngx_buf_tag_t tag; ngx_file_t *file; ngx_buf_t *shadow; /* the buf's content could be changed */ unsigned temporary:1; /* * the buf's content is in a memory cache or in a read only memory * and must not be changed */ unsigned memory:1; /* the buf's content is mmap()ed and must not be changed */ unsigned mmap:1; unsigned recycled:1; unsigned in_file:1; unsigned flush:1; unsigned sync:1; unsigned last_buf:1; unsigned last_in_chain:1; unsigned last_shadow:1; unsigned temp_file:1; unsigned zerocopy_busy:1; /* STUB */ int num;};
下面是一个 大数据池,当申请的内存不够用的时候,就使用大内存。
typedef struct ngx_pool_large_s ngx_pool_large_t;
struct ngx_pool_large_s { ngx_pool_large_t *next; void *alloc;};
typedef struct { ngx_fd_t fd; u_char *name; ngx_log_t *log;} ngx_pool_cleanup_file_t;
struct ngx_log_s {
ngx_uint_t log_level;
ngx_open_file_t *file;
ngx_atomic_uint_t connection;
ngx_log_handler_pt handler;
void *data;
/*
* we declare "action" as "char *" because the actions are usually
* the static strings and in the "u_char *" case we have to override
* their types all the time
*/
char *action;
};
下面的是用来清理内存的。
typedef struct ngx_pool_cleanup_s ngx_pool_cleanup_t;
struct ngx_pool_cleanup_s {
ngx_pool_cleanup_pt handler;
void *data;
ngx_pool_cleanup_t *next;
};
以上是起数据元素了,直接用代码可能看不懂,但是你要画出来就可能明白了
如下图所示
今天只是简单介绍了内存的大概结构,下面一篇文章将介绍如何使用内存池
更多文章欢迎访问:http://blog.csdn.net/wallwind