apache的内存池与内存分配(1)

一  内存池的代码结构

/*****************************************************************

 *
 * Managing free storage blocks...
 *from os.c in apache v1.3.34
 */
 
union align {
    /* Types which are likely to have the longest RELEVANT alignment
     * restrictions...
     */
    char *cp;
    void (*f) (void);
    long l;
    FILE *fp;
    double d;
};
 
union block_hdr {
    union align a;
 
    /* Actual header... */
 
    struct {
       char *endp;
       union block_hdr *next;
       char *first_avail;
#ifdef POOL_DEBUG
       union block_hdr *global_next;
       struct pool *owning_pool;
#endif
    } h;
};
 
struct pool {
    union block_hdr *first;
    union block_hdr *last;
    struct cleanup *cleanups;
    struct process_chain *subprocesses;
    struct pool *sub_pools;
    struct pool *sub_next;
    struct pool *sub_prev;
    struct pool *parent;
    char *free_first_avail;
#ifdef ALLOC_USE_MALLOC
    void *allocation_list;
#endif
#ifdef POOL_DEBUG
    struct pool *joined;
#endif
};   //复杂的链表结构,支持嵌套定义
//从内存池里获取内存
pool * ap_get_shared_mem_pool(size_t size)
{
    pool *new_pool;
    union block_hdr *blok;
 
    blok = (union block_hdr *) ap_tpf_get_shared_mem(size);
    /* if shm fails, it will exit blok will be valid here */
    memset((char *) blok, '/0', size);
    blok->h.next = NULL;
    blok->h.first_avail = (char *) (blok + 1);
    blok->h.endp = size + blok->h.first_avail;
    new_pool = (pool *) blok->h.first_avail;
    blok->h.first_avail += POOL_HDR_BYTES;
    new_pool->free_first_avail = blok->h.first_avail;
    new_pool->first = new_pool->last = blok;
 
    return new_pool;
}
 
 
/*****************************************************************
 *
 *from http_main.c in apache v1.3.34
 */
static pool *pglobal;              /* Global pool */
static pool *pconf;         /* Pool for config stuff */
static pool *plog;           /* Pool for error-logging files */
static pool *ptrans;        /* Pool for per-transaction stuff */
static pool *pchild;        /* Pool for httpd child stuff */
static pool *pmutex;            /* Pool for accept mutex in child */
static pool *pcommands;       /* Pool for -C and -c switches */

 二 文档说明

   这种工作方式是这样:用于处理特定请求而分配的内存、打开的文件 与一个为该请求分配的资源池绑定。池是一个自身跟踪问题资源的数据结构。

   然而,使用它有两个好处: 分配到池中的内存永远不会泄漏(即使你分配了一个临时串又忘了释放它); 以及,对于内存分配,ap_palloc通常比malloc快。

池中的内存分配

调用ap_palloc把内存分配到池中,它有两个参数, 一个是指向资源池数据结构的指针,另一个是要分配的内存数量(按char计算)。 在请求处理器内部,得到资源池指针的最普通的方式是察看相关的 request_rec结构的pool槽; 因此模块代码中常见下列程序段重复出现:
int my_handler(request_rec *r)
{
struct my_structure *foo;
...

foo = (foo *)ap_palloc (r->pool, sizeof(my_structure));
}
注意没有ap_pfree函数 --- ap_palloc分配的内存只在相关联的资源池清空时被释放。这意味着ap_palloc不必做像malloc()那样多的计算; 典型情况下它要做的就是对齐分配大小,生成块指针,再做一个范围检查。
(也存在ap_palloc的重负载使用导致一个服务进程变得过份庞大的可能性。有两个解决办法;简单地,你可以用malloc并确信所有分配的内存都显式地用 free释放了,或者你可以在主资源池里分配一个子资源池, 在子资源池里分配内存并周期性地清空它。后一个技术在下面关于子资源池的章节里有讨论,,在列目录的代码中有实际使用,主要是为了对数以千计的文件列目录时避免过多的存储分配。)。
注释:ap_palloc ap_pcalloc        from allow.c
分配初始化的内存
有几个函数用于分配初始化的内存,使用很频繁。 函数ap_pcallocap_palloc有同样的界面,但是会在返回之前清零所分配内存。 函数ap_pstrdup以一个资源池和一个char *为参数,为指针指向的字符串的拷贝分配内存并返回拷贝的指针。 最后ap_pstrcat是个参数表可变的函数,它的参数有一个资源池指针和至少两个以NULL结尾的char *。它要为每个字符串的拷贝的合并分配足够的内存。例如:
ap_pstrcat (r->pool, "foo", "/", "bar", NULL);
返回一个指向包含8个字节、已被初始化为"foo/bar"的一块内存的指针。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值