分析nginx数组ngx_array_t的设计与实现

技术文档网 2021-06-30

nginx数组结构设计

nginx数组结构的设计依赖于nginx内存池的设计

*    nginx数组的使用是依赖ngx内存池的
*    并且nginx数组是设计用来存储小数据的
*/
typedef struct {
    void        *elts;        //数组的内存地址,首元素指针
    ngx_uint_t   nelts;        //未使用元素的索引
    size_t       size;        //每个元素的大小
    ngx_uint_t   nalloc;    //分配元素个数
    ngx_pool_t  *pool;        //内存池,就是整个内存池的首节点
} ngx_array_t;
  • nginx提供了四个外部调用的接口
    • ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
      • 从内存池中申请内存创建一个nginx数组管理结构,每个元素大小为size,一共n个元素。
    • ngx_array_destroy(ngx_array_t *a)
      • 销毁数组,需要注意的是销毁工作分两步,1.销毁数组元素的内存;2.销毁数组管理结构的内存。
    • ngx_array_push(ngx_array_t *a)
      • 增加一个元素,如果原来分派这个内存的pool的d->last和数组的结束地址重合并且pool中有足够的内存在分配一个元素,则在这个pool上直接分配,否则重新申请一个2倍大小的数组;原来的数组内存并不释放。
    • ngx_array_push_n(ngx_array_t *a,ngx_uint_t n)
      • 增加n个数组元素,实现与ngx_array_push()相同;

        nginx数组内存使用总结

  • ngxin数组内存使用是继承了ngxin内存池的思想,要么不释放,要么全释放(pool),所以对于这个特征,nginx的数组使用与小内存的数组使用,如果数组元素占用的内存较大,那么在扩容的时候就会把之前的内存搁置,不释放也不能被使用。
  • 对于nginx数组扩容方面,每次扩容到原来数组大小的两倍,这样的设计可以更加容易的命中数组直接扩容的条件
          /*
          *    数组结束位置是d.last         就是pool的可用位置
          *    并且pool剩余内存足够分配一个size的数组元素
          */
          if ((u_char *) a->elts + size == p->d.last
              && p->d.last + a->size <= p->d.end)
    
    这种思想在程序设计上可以应用,使用这种贪心分配(自己发明的说法,就是多分配)让程序更容易命中高性能的程序代码。

相关文章

  1. app多版本的服务端部署

    背景 手机客户端按一定周期发版,但是客户不一定会及时更新到最新版本,所以需要服务端能支持旧版手机客户端。 服务端支持旧版手机客户端的方式主要有: 相同的接口支持不同版本手机端的请求,需要服务端接口

  2. 反向代理时URI的处理

    当使用proxy_pass的时候,请求的URI传递给服务器是有一定的规则的。 proxy_pass带有URI 比如下面的配置: location /name/ { proxy_pass htt

  3. nginx-echo-命令引发的探索

    起因 最初在 nginx.conf 中调试时,当时希望 echo 出对应的变量值,并没有成功。起初认为是 nginx 安装时,并没有安装 echo 模块,然而事后发现实际用的是 openresty,o

  4. nginx499状态码产生的原因

    什么是 nginx 的 499 499 是 nginx 扩展的 4xx 错误,目的只是用于记录,并没有实际的响应。看一下 nginx 源码 ngx_http_request.h 对 499 的定义:

  5. Nginx配置文件参数说明

    定义Nginx运行的用户和用户组 user www www; nginx进程数,建议设置为等于CPU数量*核数。 worker_processes 8; 全局错误日志定义类型,[ debug |

随机推荐

  1. app多版本的服务端部署

    背景 手机客户端按一定周期发版,但是客户不一定会及时更新到最新版本,所以需要服务端能支持旧版手机客户端。 服务端支持旧版手机客户端的方式主要有: 相同的接口支持不同版本手机端的请求,需要服务端接口

  2. 反向代理时URI的处理

    当使用proxy_pass的时候,请求的URI传递给服务器是有一定的规则的。 proxy_pass带有URI 比如下面的配置: location /name/ { proxy_pass htt

  3. nginx-echo-命令引发的探索

    起因 最初在 nginx.conf 中调试时,当时希望 echo 出对应的变量值,并没有成功。起初认为是 nginx 安装时,并没有安装 echo 模块,然而事后发现实际用的是 openresty,o

  4. nginx499状态码产生的原因

    什么是 nginx 的 499 499 是 nginx 扩展的 4xx 错误,目的只是用于记录,并没有实际的响应。看一下 nginx 源码 ngx_http_request.h 对 499 的定义:

  5. Nginx配置文件参数说明

    定义Nginx运行的用户和用户组 user www www; nginx进程数,建议设置为等于CPU数量*核数。 worker_processes 8; 全局错误日志定义类型,[ debug |