nginx学习(一)内存

网上有很多关于内存的学习,此学习的目的是为了能将内存用法化为自己的东西灵活用在别处.总体思路是化整为零.

参考其它的文章地址:http://blog.csdn.net/v_july_v/article/details/7040425

先依此画张图:

内存池的结构比较简单,有几点需特别说明:

1)内存池在使用之前需创建,如

    pool = ngx_create_pool(1024, NULL);

2)在使用内存池的时候均通过p = ngx_palloc(pool, 512);分配内存.

3)第一个内存块与后续的内存块的大小有些微的差异,以1024大小的内存池为例,第一个内存块的数据区大小为1024-sizeof(ngx_pool_s) = 984,第二个以及后续的内存块的数据区的大小则为1024-sizeof(ngx_pool_data_t) = 1008,如上图所示.

4)关于字段failed,源代码中有这样一组代码:

    for (p = current; p->d.next; p = p->d.next) {
        if (p->d.failed++ > 4) {
            current = p->d.next;
        }
    }

之前一直不理解,网上很多人说是一组经验值,后来写了好些测试代码,不停分配内存池,突然想明白了,也明白了pool->current不一定指向当前内存块的意思.理解如下:

内存池实际上是一个链式结构,如果分配内存的时候总是从头开始,一旦内存池中的块特别多,则会影响效率,因此增加了一个current的指针,当分配策略达到一定程度的时候,将current后移,后面的分配不再使用current之前的内存(即使之前的内存块可用),这样以空间换时间,使得效率尽可能高.

5)内存池的分配一旦调用了ngx_palloc,p指向的是分配的内存,此时当前的内存池中的last变量已经指向了当前内存的末端,此处特别需要注意.

测试代码如下:

void dump_pool(ngx_pool_t* pool)
{
    while (pool)
    {
        printf("pool = 0x%x\n", pool);
        printf("  .d\n");
        printf("    .last = 0x%x\n", pool->d.last);
        printf("    .end = 0x%x\n", pool->d.end);
        printf("    .next = 0x%x\n", pool->d.next);
        printf("    .failed = %d\n", pool->d.failed);
        printf("  .max = %d\n", pool->max);
        printf("  .current = 0x%x\n", pool->current);
        printf("  .chain = 0x%x\n", pool->chain);
        printf("  .large = 0x%x\n", pool->large);
        printf("  .cleanup = 0x%x\n", pool->cleanup);
        printf("  .log = 0x%x\n", pool->log);
        printf("available pool memory = %d\n\n", pool->d.end - pool->d.last);
        pool = pool->d.next;
    }
}

int test_main()
{
    ngx_pool_t *pool;
    char *p = NULL;
    int i = 0;

    printf("sizeof(ngx_pool_t) = %d\n", sizeof(ngx_pool_t));//ngx_pool_data_t
    printf("sizeof(ngx_pool_data_t) = %d\n", sizeof(ngx_pool_data_t));
    printf("--------------------------------\n");
    printf("create a new pool:\n");
    printf("--------------------------------\n");
    pool = ngx_create_pool(1024, NULL);
    dump_pool(pool);

    for (i = 0; i < 10; i++)
    {   
        printf("--------------------------------\n");
        printf("alloc block %d from the pool:\n", i+1);
        printf("--------------------------------\n");
        p = ngx_palloc(pool, 512);
        dump_pool(pool);
    }

    ngx_destroy_pool(pool);
    return 0;
}
原文地址:https://www.cnblogs.com/luhouxiang/p/2690161.html