6.nginx源码分析之数据结构:ngx_pool_t

[nginx] nginx内存池ngx_pool_t的介绍 本文详细介绍nginx中内存池的设计和实现。   nginx pool 由 小内存拉链、大内存拉链、回调函数拉链组成。创建的第一个ngx_pool_s头部,会作为整个pool的head,保存一些拉链信息。 1 创建一个ngx_pool: struct ngx_pool_s { ngx_pool_data_t d; size_t m... 阅读详情

nginx内存管理


nginx内存管理的结构体

关于nginx内存管理的方法在ngx_palloc.h文件中,定义了相关结构体和接口:

如下几个宏定义了内存池的默认大小和对齐大小。

/*
 * NGX_MAX_ALLOC_FROM_POOL should be (ngx_pagesize - 1), i.e. 4095 on x86.
 * On Windows NT it decreases a number of locked pages in a kernel.
 */
#define NGX_MAX_ALLOC_FROM_POOL  (ngx_pagesize - 1)

//默认大小是1024个16B
#define NGX_DEFAULT_POOL_SIZE    (16 * 1024)

#define NGX_POOL_ALIGNMENT       16
#define NGX_MIN_POOL_SIZE                                                     \
    ngx_align((sizeof(ngx_pool_t) + 2 * sizeof(ngx_pool_large_t)),            \
              NGX_POOL_ALIGNMENT)

定义了nginx的FREE函数指针,ngx_pool_cleanup_pt为一个函数指针,他可以指向用户希望采用的释放函数。


typedef void (*ngx_pool_cleanup_pt)(void *data);

接下来是相关结构体,该结构体是一个链表的节点结构,该节点记录着一个特殊的需要释放的资源。

typedef struct ngx_pool_cleanup_s  ngx_pool_cleanup_t;
struct ngx_pool_cleanup_s {
    ngx_pool_cleanup_pt   handler;
    void                 *data;
    ngx_pool_cleanup_t   *next;
};

handler 记录着资源的释放策略;
data是实际所指向的资源的地址;
next就是链表的下一个节点位置;

因为nginx的内存释放是在最后进行的,所以需要记录下每个资源的释放规则(由handler记录着函数地址)。

typedef struct ngx_pool_large_s  ngx_pool_large_t;

struct ngx_pool_large_s {
    ngx_pool_large_t     *next;    //指向下一个pool
    void                 *alloc;    //指向分配的内存
};  
typedef struct {
    u_char               *last;      //内存池下一次分配的起始位置
    u_char               *end;       //内存池结束位置
    ngx_pool_t           *next;      //内存池里面有很多块内存,这些内存块就是通过该指针连成链表的
    ngx_uint_t            failed;    //内存分配失败次数
} ngx_pool_data_t;   //内存池数据块信息

内存池的控制信息如下,上述内存池数据块ngx_pool_data_t信息是当前这个内存池的描述信息,所以其实是ngx_pool_s的一部分,作为控制信息我们把它放在了ngx_pool_s的开始位置。

struct ngx_pool_s {
    ngx_pool_data_t       d;
    size_t                max;
    ngx_pool_t           *current;
    ngx_chain_t          *chain;
    ngx_pool_large_t     *large;
    ngx_pool_cleanup_t   *cleanup;
    ngx_log_t            *log;
};

d 是当前内存块的控制信息;
max 是小块内存申请的最大值,如果比这个大就算是大块内存;
current 当前内存池本身的地址
chain 指向了一个chain结构
large 指向一个大块内存的地址(大小大鱼max的内存,nginx使用标准库malloc进行申请)
cleanup 指向nginx释放结构体的指针
log 指向日志结构体

各个结构体的关系如下图所示(该图由JULY绘制,借鉴过来):
这里写图片描述


nginx内存管理的接口

上述是内存管理的结构体定义,在C编程中,一旦结构体定义OK,剩下的接口实现基本都是围绕着结构体展开的。nginx向我们介绍了如下几个接口定义:

//nginx的内存申请
void *ngx_alloc(size_t size, ngx_log_t *log);
void *ngx_calloc(size_t size, ngx_log_t *log);

//nginx创建内存池,销毁内存池,重置内存池
ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log);
void ngx_destroy_pool(ngx_pool_t *pool);
void ngx_reset_pool(ngx_pool_t *pool);

//在内存池进行资源的申请和释放
void *ngx_palloc(ngx_pool_t *pool, size_t size);
void *ngx_pnalloc(ngx_pool_t *pool, size_t size);
void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
void *ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment);
ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);


ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size);
void ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd);
void ngx_pool_cleanup_file(void *data);
void ngx_pool_delete_file(void *data);

下面我们对这些接口进行逐个分析,接口的实现在ngx_palloc.c文件中:


ngx_alloc

void * ngx_alloc(size_t size, ngx_log_t *log)
{
    void  *p;

    p = malloc(size);   //ngx_alloc申请内存只是对malloc的封装
    //不管是申请成功还是失败都会写入日志
    if (p == NULL) {   
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                      "malloc(%uz) failed", size);
    }

    ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0, "malloc: %p:%uz", p, size);

    return p;
}

ngx_calloc

void * ngx_calloc(size_t size, ngx_log_t *log)
{   
    void  *p;

    p = ngx_alloc(size, log);

    if (p) {
        ngx_memzero(p, size);    //将ngx_alloc申请的内存全部清空
    }

    return p;
}   

ngx_create_pool 创建ngx内存池操作

ngx_pool_t * ngx_create_pool(size_t size, ngx_log_t *log)
{       
    ngx_pool_t  *p;    //创建nginx内存池的控制结构

    p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);

    if (p == NULL) {
        return NULL;
    }              

    //对nginx控制结构的值进行初始化
    p->d.last = (u_char *) p + sizeof(ngx_pool_t);
    //因为内存池可申请的内存要避开控制信息,所以可申请内存的初始化起始地址要从控制信息的下一个字节开始
    p->d.end = (u_char *) p + size;    //指定可申请内存的终止地址
    p->d.next = NULL;    //下一个内存池地址为空
    p->d.failed = 0;     //内存池申请的数目起始位置为空

    size = size - sizeof(ngx_pool_t);    //可申请的内存大小要去除控制信息(ngx_pool_t)
    p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;   //判定大内存的大小

    p->current = p;    //当前内存块的地址指向p本身
    p->chain = NULL;     //链表指针地址
    p->large = NULL;      //刚开始还没有大内存申请,所以指针为NULL
    p->cleanup = NULL;     //清空模块的指针为空
    p->log = log;         //日志结构体指针进行初始化

    return p; 
}   

内存池的初始化没有采用malloc直接申请,而是使用了ngx_memalign函数,ngx_memalign的实现如下:

void * ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
{
    void  *p;
    int    err;

    err = posix_memalign(&p, alignment, size);

    if (err) {
        ngx_log_error(NGX_LOG_EMERG, log, err,
                      "posix_memalign(%uz, %uz) failed", alignment, size);
        p = NULL;
    }

    ngx_log_debug3(NGX_LOG_DEBUG_ALLOC, log, 0,
                   "posix_memalign: %p:%uz @%uz", p, size, alignment);

    return p;
}

这个函数中真正起申请作用的是posix_memalign,posix_memalign的接口定义如下:

int posix_memalign (void **memptr,    //内存申请指针的地址
                    size_t alignment,    //申请的内存是alignment的倍数,alignment的2的幂,这样设计是为了方便操作
                    size_t size);    //size是我们申请的内存的大小

ngx_create_pool 调用最终会得到一个内存池的控制信息以及对其成员的初始化:


ngx_destroy_pool内存池的销毁操作

代码实现如下:

void
ngx_destroy_pool(ngx_pool_t *pool)
{
    ngx_pool_t          *p, *n;
    ngx_pool_large_t    *l;
    ngx_pool_cleanup_t  *c;

    for (c = pool->cleanup; c; c = c->next) {
        if (c->handler) {
            ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                           "run cleanup: %p", c);
            c->handler(c->data);
        }
    }

#if (NGX_DEBUG)

    /*
     * we could allocate the pool->log from this pool
     * so we cannot use this log while free()ing the pool
     */

    for (l = pool->large; l; l = l->next) {
        ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
    }

    for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
        ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                       "free: %p, unused: %uz", p, p->d.end - p->d.last);

        if (n == NULL) {
            break;
        }
    }

#endif

    for (l = pool->large; l; l = l->next) {
        if (l->alloc) {
            ngx_free(l->alloc);
        }
    }

    for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
        ngx_free(p);

        if (n == NULL) {
            break;
        }
    }
}

在C语言中,因为没有类的概念,也就不存在类的销毁,所以资源的释放顺序一定要严格的把控。以ngx_pool_t为例,它其中包含了ngx_pool_large_t和ngx_pool_cleanup_t这些结构体指针,释放顺序如下:
(1)首先在清楚链表中使用用户指定的方式( handler
所指向的函数)释放节点的data数据。

for (c = pool->cleanup; c; c = c->next) {
        if (c->handler) {
            ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                           "run cleanup: %p", c);
            c->handler(c->data);
        }
    }

(2)接着释放大块内存链表,其中的ngx_free就是标准库中的free函数封装:

for (l = pool->large; l; l = l->next) {
        if (l->alloc) {
            ngx_free(l->alloc);
        }
    }

(3)最后我们释放nginx的内存池链表,这里采用的是双指针联动方式,让p指向当前内存池地址,而n指向下一个内存池,先释放当前的内存池,再判断下一个内存池是否存在,如果不存在则循环结束:

for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
        ngx_free(p);

        if (n == NULL) {
            break;
        }
    }

ngx_reset_pool 重置内存池

void ngx_reset_pool(ngx_pool_t *pool)
{
    ngx_pool_t        *p;
    ngx_pool_large_t  *l;

    for (l = pool->large; l; l = l->next) {
        if (l->alloc) {
            ngx_free(l->alloc);
        }
    }

    for (p = pool; p; p = p->d.next) {
        p->d.last = (u_char *) p + sizeof(ngx_pool_t);
        p->d.failed = 0;
    }

    pool->current = pool;
    pool->chain = NULL;
    pool->large = NULL;
}

这个流程和销毁内存池操作有着相同的部分,先清空大内存池的链表,之前的那个cleanup链表的销毁操作可以不进行,反正在内存池执行销毁的时候也会执行,然后把last指针指向控制信息的下一个字节地址。


ngx_palloc内存池申请内存

这里对申请的内存大小做判断,选择大内存申请或者小内存申请方式,注意这里申请的内存大小是经过对齐的,而ngx_pnalloc申请的内存大小是没有对齐的。

void *
ngx_palloc(ngx_pool_t *pool, size_t size)
{
#if !(NGX_DEBUG_PALLOC)
    if (size <= pool->max) {
        return ngx_palloc_small(pool, size, 1);
    }
#endif

    return ngx_palloc_large(pool, size);
}

这里主要关注两个函数ngx_palloc_small和ngx_palloc_large。

ngx_palloc_small

static ngx_inline void *
ngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)
{
    u_char      *m;     
    ngx_pool_t  *p;

    p = pool->current;

    do {
        m = p->d.last;

        if (align) {
            m = ngx_align_ptr(m, NGX_ALIGNMENT);
        }

        if ((size_t) (p->d.end - m) >= size) {
            p->d.last = m + size;

            return m;
        } 

        p = p->d.next;

    } while (p);

    return ngx_palloc_block(pool, size);
}   

在整个内存池链表中找到能够申请size大小的内存,把申请的起始地址返回,该内存池的可用内存大小减少size。如果遍历完当前的内存池链表都无法满足当前size大小的内存申请。则调用ngx_palloc_block(pool, size)函数,该函数的实现如下所示:

static void * ngx_palloc_block(ngx_pool_t *pool, size_t size)
{   
    u_char      *m;
    size_t       psize;
    ngx_pool_t  *p, *new;

    psize = (size_t) (pool->d.end - (u_char *) pool);

    m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
    if (m == NULL) {
        return NULL;
    }

    new = (ngx_pool_t *) m;

    new->d.end = m + psize;
    new->d.next = NULL;
    new->d.failed = 0;

    m += sizeof(ngx_pool_data_t);
    m = ngx_align_ptr(m, NGX_ALIGNMENT);
    new->d.last = m + size;

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

    p->d.next = new;

    return m;
}

该函数的作用就是申请了一个新的内存池(pool),首先计算了内存池的大小,然后进行申请,如果成功的话把地址返回给new指针,用new对内存池的结构体成员进行初始化,m是我们最后申请的内存块的首地址,但是现在需要把new这个新的内存池插入到其他的内存池的链表末尾。

ngx_palloc_large 申请大块内存

static void * ngx_palloc_large(ngx_pool_t *pool, size_t size)
{
    void              *p;
    ngx_uint_t         n;
    ngx_pool_large_t  *large;

    //大块内存的申请采用malloc直接申请
    p = ngx_alloc(size, pool->log);
    if (p == NULL) {
        return NULL;
    }

    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);
    if (large == NULL) {
        ngx_free(p);
        return NULL;
    }

    //把这个p所指向的大块内存的管理节点尾部添加到大块内存链表指针里
    large->alloc = p;
    large->next = pool->large;
    pool->large = large;

    return p;
}

ngx_pnalloc不进行对其的内存池申请

该方法的实现和ngx_palloc类似


ngx_pcalloc对内存池申请的内存初始化为0

void * ngx_pcalloc(ngx_pool_t *pool, size_t size)
{
    void *p;

    p = ngx_palloc(pool, size);
    if (p) {
    //初始化申请的内存为0
        ngx_memzero(p, size);
    }

    return p;
}

ngx_pfree 内存池释放大块内存的方法

ngx_int_t
ngx_pfree(ngx_pool_t *pool, void *p)
{
    ngx_pool_large_t  *l;

    for (l = pool->large; l; l = l->next) {
        if (p == l->alloc) {
            ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                           "free: %p", l->alloc);
            ngx_free(l->alloc);
            l->alloc = NULL;

            return NGX_OK;
        }
    }

    return NGX_DECLINED;
}

ngx_pool_run_cleanup_file清空文件描述符fd

void ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd)
{
    ngx_pool_cleanup_t       *c;
    ngx_pool_cleanup_file_t  *cf;

    for (c = p->cleanup; c; c = c->next) {
        if (c->handler == ngx_pool_cleanup_file) {

            cf = c->data;

            if (cf->fd == fd) {
                c->handler(cf);
                c->handler = NULL;
                return;
            }
        }
    }
}

小结

关于nginx的内存池管理如上所示,需要边看代码边进行画图才能加深理解,管理思路比较直接,不像c++的stl那样分配了多个自由链表。希望大家可以好好思考。

YOLO12涨点改进| 损失函数改进篇 |AAAI 2025| 一种小目标检测SDLoss损失函数,解决现有损失函数对不同目标尺度敏感度不足的局限,提高了网络检测不同尺度目标的敏感能力,助力高效涨点 本文提出了一种改进的小目标检测方法SDLoss,通过动态调整尺度损失与位置损失的权重,优化了YOLOv12模型的性能。针对红外小目标检测中存在的两个主要问题:1)标准卷积难以捕捉目标的高斯空间分布特性;2)现有损失函数对不同尺度目标的敏感度不足,研究团队开发了Pinwheel-shaped卷积(PConv)和Scale-based Dynamic损失函数(SDLoss)。PConv通过不对称卷积核设计显著提升感受野,SDLoss则根据目标大小动态平衡尺度与位置损失的影响。 阅读详情

相关推荐

开关电源EMI滤波设计:如何通过Cx和Cy电容精准抑制共模与差模干扰?

本文深入解析了开关电源EMI滤波设计中Cx和Cy电容的核心作用。Cx电容并联于火线与零线之间,专用于抑制差模干扰;Cy电容连接于火线/零线与地之间,则负责泄放共模干扰。文章详细阐述了二者选型、安规要求及PCB布局要点,并提供了基于测试频谱的实战调优策略,是解决电源传导噪声问题的实用指南。

7z8x2c4v6b9的博客 466

nginx 学习四 内存池 ngx_pool_t 和内存管理操作

这几天在看nginx,发现凡是有内存申请的地方都有pool这个东东出现,仔细看看,原来pool的类型是ngx_pool_t,是nginx用来做内存管理的,于是就决定看看他的实现。 1 nginx内存池相关的结构体      ngx_pool_t定义在core/ngx_palloc.h ngx_palloc.c中,下面是几个主要的结构体      ngx_pool_data_t typede

yanziguilai的专栏 4456

QT 面试题汇总

一、讲述Qt信号槽机制与优势与不足 优点:①类型安全。需要关联的信号槽的签名必须是等同的。即信号的参数类型和参数个数同接受该信号的槽的参数类型和参数个数相同。若信号和槽签名不一致,编译器会报错。 ②松散耦合。信号和槽机制减弱了Qt对象的耦合度。激发信号的Qt对象无需知道是那个对象的那个信号槽接收它发出的信号,它只需在适当的时间发送适当的信号即可,而不需要关心是否被接受和那个对象接受了。Qt就保证了适当的槽得到了调用,即使关联的对象在运行时被删除。程序也不会奔溃。 ...

编程菜鸟 4万+

nginx内存池c++代码及测试

#ifndef _NGX_POOL #define _NGX_POOL #define MAXSIZEPOOL 4096 #include using namespace std; class NgxPoitem { public: NgxPoitem(size_t size) :next(NULL), large(NULL) { try { data = reinterpre

我是一片云 501

无人机蜂群联合指挥作战技术详解

随着人工智能、通信技术、新材料等领域的不断进步,无人机蜂群联合指挥作战技术将迎来更加广阔的发展前景。未来,无人机蜂群将更加智能化、自主化,能够执行更加复杂、精细的作战任务。同时,加强国际合作,共同制定国际规则和标准,将是推动无人机蜂群技术健康发展的重要方向。无人机蜂群技术,是指通过先进的通信技术、自主导航与决策算法,将大量小型、低成本、功能各异的无人机组织成一个高度协同的群体,执行复杂多样的军事任务。2. 通信与数据链:采用高速、低延迟、抗干扰的通信技术,保障群体内无人机间的信息交换。

专注多旋翼、复合翼无人机技术研究,从事低空经济行业。 1544

毫米波与太赫兹:十射线模型建模

Pt=1,只考虑地面和前后两面墙的反射,反射系数为0.7。用matlab设计程序并实现该功能。,总计考虑10条路径,求出接收功率随。

SupermarketX的博客 785

Nginx基本数据结构之ngx_pool_t

ngx_pool_t是一个非常重要的数据结构,在很多重要的场合都有使用,很多重要的数据结构也都在使用它。那么它究竟是一个什么东西呢?简单的说,它提供了一种机制,帮助管理一系列的资源(如内存,文件等),使得对这些资源的使用和释放统一进行,免除了使用过程中考虑到对各种各样资源的什么时候释放,是否遗漏了释放的担心。 例如对于内存的管理,如果我们需要使用内存,那么总是从一个ngx_pool_t的对象

wangpengqi的专栏 1127

高频仿真:高频天线设计_(4).天线参数分析与优化

通过上述步骤,我们展示了如何综合使用解析方法、数值优化方法和实验数据来设计和优化一个高效宽带天线。首先,我们通过解析方法确定了天线的初步长度;然后,使用遗传算法优化了天线的直径以最大化增益;最后,通过实验数据验证了天线的性能,包括驻波比和带宽。这一综合性方法可以有效地提升天线的设计和优化效果,确保其在实际应用中表现出色。

2401_87715305的博客 923

nginx源码解析之内存池

nginx自身实现了内存池,所有内存分配都是基于内存池来操作。基本思想是预申请一段内存空间,低于指定大小的内存(小段内存)直接从内存池中申请,超过指定大小的内存(大段内存)直接调用malloc申请。相关代码在os/unix/ngx_alloc.{c,h}和core/ngx_palloc.{c,h}。

0cool 1257

RHCA II之路---EX442-10

这题比较耗时,可以多开2个窗口让他跑起来后先做后面的题目。

Q先生 584

串行RapidIO(Serial RapidIO,SRIO):协议介绍

目录一、RapidIO背景介绍二、RapidIO协议概述2.1 包与控制符号2.2 包格式2.4 消息传递2.5 全局共享存储器2.6 流量控制2.7 串行物理层三、I/O逻辑操作与包格式四、维护操作与包格式五、消息操作与包格式六、总结 本文是基于Xilinx平台SRIO介绍(一)RapidIO协议介绍的内容作读书笔记。 一、RapidIO背景介绍 RapidIO采用三层分级体系结构,包括逻辑层、传输层和物理层该分级结的如下图所示: ● 逻辑层:位于最高层,定义全部协议和包的格式,它们为端点器件发起和完

Starry__的博客 1万+

nginx源码分析—内存池结构ngx_pool_t及内存管理

本博客(http://blog.csdn.net/livelylittlefish)贴出作者(阿波)相关研究、学习内容所做的笔记,欢迎广大朋友指正!Content0. 序1. 内存池结构1.1 ngx_pool_t结构1.2 其他相关结构1.3 ngx_pool_t的逻辑结构2. 内存池操作2.1 创建内存池2.2 销毁内存池2.3 重置内存池2.4 分配内存2.4.1 ngx_palloc()函

学习,思考,记录,分享。 3万+

游戏引擎定制化:大厂如何玩转性能极限(大白话生动有趣版)

游戏大厂如何深度定制游戏引擎?本文系统解析了商业引擎的局限性及大厂定制化的核心诉求。主要内容包括: 大厂定制引擎的根本原因:性能瓶颈、差异化需求、自有生态整合等 主流引擎的优劣势对比及适用场景 定制化重点领域:渲染管线优化、物理系统重构、网络架构改造等 全流程定制方案:从需求分析到模块重构再到工具链开发 典型案例:如腾讯CF手游的渲染优化、原神的热更新系统等 文章指出,顶级游戏产品必须对引擎核心模块动刀,通过深度定制实现性能突破和创新功能开发。同时提供了风险规避建议和技术演进趋势,为游戏开发者提供了宝贵的实

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 634

Nginx源码分析:核心数据结构ngx_cycle_t与内存池概述

nginx源码分析 nginx-1.11.1 参考书籍《深入理解nginx模块开发与架构解析》 核心数据结构与内存池概述 在Nginx中的核心数据结构就是ngx_cycle_t结构,在初始化的过程中就首先初始化了ngx_cycle_t结构,无论是master或者worker进程都初始化了该结构,本文就会分析该结构中的相关作用与成员;本文也会对Nginx的内存管理进行相关的分析,Nginx的内存管...

qq_33339479的博客 614

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_create_pool函数

定义一个指针变量p,用于存储新创建的内存池对象的地址。

weixin_41812346的博客 706

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Nginx源码分析——ngx_pool_t内存池

引言: C/C++下内存管理是让几乎每一个程序员头疼的问题,分配足够的内存、追踪内存的分配、在不需要的时候释放内存——这个任务相当复杂。而直接使用系统调用malloc/free、new/delete进行内存分配和释放,有以下弊端: 调用malloc/new,系统需要根据“最先匹配”、“最优匹配”或其他算法在内存空闲块表中查找一块空闲内存,调用free/delete,系统可能需要合并空闲

Much effort, much prosperity. 543

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

结构体全局变量_nginx源码分析—内存池结构ngx_pool_t及内存管理

0. 序 nginx对内存的管理由其自己实现的内存池结构ngx_pool_t来完成,本文重点叙述nginx的内存管理。 nginx内存管理相关文件:(1) ./src/os/unix/ngx_alloc.h/.c内存相关的操作,封装了最基本的内存分配函数如free/malloc/memalign/posix_memalign,分别被封装为ngx_free,ngx_alloc/ngx_calloc,...

weixin_39845430的博客 119

nginx源码分析—全局变量ngx_cycle的初始化

作者:阿波 链接:http://blog.csdn.net/livelylittlefish/article/details/7247080 Content 0.序 1. ngx_cycle_t结构 2. ngx_init_cycle()分析 3.注意问题 3.1如何调用CORE模块的callback函数? 3.2 open_files链表中的文件名何时初始化? 4.小结

学习,思考,记录,分享。 2万+

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_pool_t 类型

ngx_pool_t定义在 src/core/ngx_core.h。

weixin_41812346的博客 408

Nginx源码分析—数组结构ngx_array_t

.Nginx源码分析—数组结构ngx_array_t     ngx_array_t结构:     struct ngx_array_s{         void  *elts;//数组数据区起始位置         ngx_uint_t   netls;//数据区实际存放的元素个数;         size_t       size;//每一个元素的个数;         ngx

Cassie_Yan的博客 481

ngx_create_pool

【代码】ngx_create_pool。

weixin_41812346的博客 508

Nginx源码分析(3)之——内存池(ngx_pool_t)分析

Nginx源码分析 内存池分析 ngx_pool_t

hnudlz的专栏 1032

nginx共享内存原理和源码分析

简介 nginx 共享内存是利用 mmap 将内容存储在内存中以及自旋锁。当 master 启动的时候, 根据相应的指令去初始化共享内存。利用共享内存实现一个轻量级的 k/v 系统。 全局变量 ngx_cycle_s 结构 struct ngx_cycle_s { void ****conf_ctx; //配置上下文数组(含所有模块) ngx_pool_t *pool; //内存池 ngx_log_t *log; //日志 ngx_log_t new_log; ngx_conne

focus on security 1892

nginx数组结构ngx_array_t剖析

nginx数组结构ngx_array_t剖析 1. 序       nginx自定义了很多数据结构,其中很多的程序都需要用到这些复杂的数据结构,如:数组,链表,红黑树等,在这里可以通过源码看每个数据结构的实现,在博客中不准备针对每个数据结构进行讲解,这里抽取ngx_array_t数组结构。 2. 数组结构 2.1 ngx_array_t结构      nginx的数组

chenglinhust的专栏 1488

【Nginx 源码学习】内存池 及 优秀案例赏析:Nginx内存池设计

看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面小编专门为你量身定制了一套针对知识面不够,也莫慌!还有一整套的,可以瞬间查漏补缺全都是一丢一丢的收集整理纯手打出来的。

2401_84010497的博客 1146

Nginx源码阅读(ngx_pool_t)

// src/core/ngx_palloc.hstruct ngx_pool_s { ngx_pool_data_t d; size_t max; /* 全部可使用内存的大小,包含已使用和未使用内存。 区别小块和大块内存的标准,小于等于max为小块内存,大于max为大块内存

Jiajun Zhu 507
上一篇: 5.nginx源码分析之数据结构:ngx_string
下一篇: 7.nginx源码分析之数据结构:ngx_array_t
linux_player_c
博客等级 码龄13年 214粉丝 134原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值