[置顶] Ngnix 源码学习(3)----内存池结构

时间:2022-05-13 16:12:07
本篇首先把 内存池结构 大概的说一下,具体使用将在下一节细致描述

 

首先知道内存池的作用

    为什么需要内存池?

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;
};


以上是起数据元素了,直接用代码可能看不懂,但是你要画出来就可能明白了

如下图所示[置顶]        Ngnix 源码学习(3)----内存池结构
[置顶]        Ngnix 源码学习(3)----内存池结构

 

今天只是简单介绍了内存的大概结构,下面一篇文章将介绍如何使用内存池

更多文章欢迎访问:http://blog.csdn.net/wallwind