本篇首先把 內存池結構 大概的說一下,具體使用將在下一節細緻描述
首先知道內存池的作用
爲什麼需要內存池?
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