• nginx开发_ngx_palloc源码解析


    功能简介

    ngx_pool_t是nginx开发中最经常使用到的内存容器。对动态内存的封装,由框架进行创建与释放,模块开发过程中仅需要进行内存申请,不需要关注何时释放。常见的pool对象有:

    1、 ngx_init_cycle()创建的cycle->pool。常见的cf->pool也是指向cycle->pool,这个pool的生命周期很长,直到进程退出ngx_worker_process_exit()/ngx_master_process_exit()才释放。

    2、ngx_http_create_request()创建的r->pool,在ngx_http_free_request()时释放。

    3、ngx_event_accept()创建的c->pool,在ngx_http_close_connection()/ngx_close_accepted_connection()时释放。

    使用方式

    模块开发中的使用方式很简单只有一组申请接口,一般不需要主动释放:

    void *ngx_palloc(ngx_pool_t *pool, size_t size);
    void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
    

    最常用的是这2个接口,差别在于是否对申请获得的空间进行初始化赋0操作。

    数据结构

    pool内部的核心数据结构与指针引用如下图

    内部将内存划分为small/large2种,边界是p->max。

    //ngx_create_pool(size_t size, ngx_log_t *log)
    p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
    
    //ngx_palloc(ngx_pool_t *pool, size_t size)
    if (size <= pool->max) {
        return ngx_palloc_small(pool, size, 1);
    }
    return ngx_palloc_large(pool, size);
    
    • 首先通过malloc()申请一份空间A,用于存放pool相关结构体。

    • 如果用户申请的是small内存,则直接在空间A中申请。通过d.lastd.end维护剩余空间。

    • 如果用户申请的是large内存,则在空间A中新建一个ngx_pool_large_t结构体,并通过malloc申请新空间。通过nextalloc维护large内存链。

    • 如果空间A余量不足,则在申请一份空间A,通过p->currentd.next作为链表维护。

    • 释放Pool时要释放large空间与空间A。

    • ngx_pfree()接口,如果时large空间则释放,small空间不做处理。

    算法

    • 申请large空间时会优先查找是否有空闲的ngx_pool_large_t,但仅尝试前3个。
    //ngx_palloc_large(ngx_pool_t *pool, size_t size)
    n = 0;
    for (large = pool->large; large; large = large->next) {
        if (large->alloc == NULL) {
            large->alloc = p;
            return p;
        }
        if (n++ > 3) {
            break;
        }
    }
      large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
    
  • 相关阅读:
    [USACO 5.5]Hidden Password
    [Codeforces 1016F]Road Projects
    再会,OI
    [TJOI 2018]智力竞赛
    [POI 2009]Lyz
    [NOI 2015]品酒大会
    [NOI 2017]蔬菜
    [NOI 2017]整数
    [NOI 2017]游戏
    [NOI 2017]蚯蚓排队
  • 原文地址:https://www.cnblogs.com/atskyline/p/8677895.html
Copyright © 2020-2023  润新知