• 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;
    }
  • 相关阅读:
    【如何在mysql 官网下载最新版本mysql 数据库】
    【17-类加载与反射】
    【16-网络编程】
    【14-输入/输出】
    【13-Annotation】
    【12-JDBC编程】
    C# SqlHelper类的数据库操作
    C# DateTime与时间戳转换
    C#递归方法遍历目录及子目录
    C# SaveFileDialog的用法
  • 原文地址:https://www.cnblogs.com/luhouxiang/p/2690161.html
Copyright © 2020-2023  润新知