将nginx内存池代码单独编译运行,了解nginx内存池工作原理,附代码

news2025/5/16 14:39:43

初识nginx——内存池篇

https://www.cnblogs.com/magicsoar/p/6040238.html

 为了自身使用的方便,Nginx封装了很多有用的数据结构,比如ngx_str_t ,ngx_array_t, ngx_pool_t 等等,对于内存池,nginx设计的十分精炼,值得我们学习,本文介绍内存池基本知识,nginx内存池的结构和关键代码,并用一个实际的代码例子作了进一步的讲解

一、内存池概述
内存池是在真正使用内存之前,预先申请分配一定数量的、大小相等(一般情况下)的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够用时,再继续申请新的内存。

内存池的好处有减少向系统申请和释放内存的时间开销,解决内存频繁分配产生的碎片,提示程序性能,减少程序员在编写代码中对内存的关注等

目前一些常见的内存池实现方案有STL中的内存分配区,boost中的object_pool,nginx中的ngx_pool_t,google的开源项目TCMalloc等

二、nginx内存池综述
nginx为每一个层级都会创建一个内存池,进行内存的管理,比如一个模板,tcp连接,http请求等,在对应的生命周期结束的时候会摧毁整个内存池,把分配的内存一次性归还给操作系统。

 在分配的内存上,nginx有小块内存和大块内存的概念,小块内存 nginx在分配的时候会尝试在当前的内存池节点中分配,而大块内存会调用系统函数malloc向操作系统申请

 在释放内存的时候,nginx没有专门提供针对释放小块内存的函数,小块内存会在ngx_destory_pool 和 ngx_reset_pool的时候一并释放

 区分小块内存和大块内存的原因有2个,

 1、针对大块内存  如果它的生命周期远远短于所属的内存池,那么提供一个单独的释放函数是十分有意义的,但不区分大块内存和小块内存,针对大的内存块 便会无法提前释放了

 2、大块内存与小块内存的界限是一页内存(p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL,NGX_MAX_ALLOC_FROM_POOL的值通过调用getpagesize()获得),大于一页的内存在物理上不一定是连续的,所以如果分配的内存大于一页的话,从内存池中使用,和向操作系统重新申请效率差不多是等价的


  nginx内存池提供的函数主要有以下几个

在这里插入图片描述

三、nginx内存池详解
nginx使用了ngx_pool_s用于表示整个内存池对象,ngx_pool_data_t表示单个内存池节点的分配信息,ngx_pool_large_s表示大块内存

它们的结构和含义如下

struct ngx_pool_large_s {
ngx_pool_large_t *next;
void *alloc;
};

next: 指向下一个大块内存

alloc:指向分配的大块内存

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: 指向一个ngx_chain_t结构

large: 指向大块内存链表

cleanup:释放内存池的callback

log: 用于输出日志

typedef struct {
u_char *last;
u_char *end;
ngx_pool_t *next;
ngx_uint_t failed;
} ngx_pool_data_t;

last: 内存池节点已分配的末位地址,下一次分配会尝试从此开始

end: 内存池节点的结束位置

next:next指向下一个内存池节点

failed: 当前内存池节点分配失败次数

NewImage

   nginx 内存池示意图1



在分配内存的时候,nginx会判断当前要分配的内存是小块内存还是大块内存,大块内存调用ngx_palloc_large进行分配,小块内存nginx先会尝试从内存池的当前节点(p->current)中分配,如果内存池当前节点的剩余空间不足,nginx会调用ngx_palloc_block新创建一个内存池节点并从中分配,

如果内存池当前节点的分配失败次数已经大于等于6次(p->d.failed++ > 4),则将当前内存池节点前移一个

(这里有个需要注意的地方,当当前内存节点的剩余空间不够分配时,nginx会重新创建一个ngx_pool_t对象,并且将pool.d->next指向新的ngx_pool_t,新分配的ngx_pool_t对象只用到了ngx_pool_data_t区域,并没有头部信息,头部信息部分已经被当做内存分配区域了)

NewImage

             nginx 内存池示意图2(新建了一个内存池节点和分配了2个大块内存,其中一个已经释放) 

完成代码,可在linux运行

//-------------------------------------------------------------------------------------------
//下面是一些头文件和宏定义,从nginx的源码中摘录过来
#include </usr/include/stdint.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdarg.h>
#include <stddef.h> /* offsetof() /
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <pwd.h>
#include <grp.h>
#include <dirent.h>
#include <glob.h>
#include <sys/vfs.h> /
statfs() */

#include <sys/uio.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sched.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h> /* TCP_NODELAY, TCP_CORK */
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/un.h>

#include <time.h> /* tzset() /
#include <malloc.h> /
memalign() /
#include <limits.h> /
IOV_MAX /
#include <sys/ioctl.h>
#include <crypt.h>
#include <sys/utsname.h> /
uname() */

#include <dlfcn.h>

#ifndef ngx_inline
#define ngx_inline inline
#endif

typedef int ngx_fd_t;
typedef intptr_t ngx_int_t;
typedef uintptr_t ngx_uint_t;
typedef intptr_t ngx_flag_t;
typedef struct ngx_module_s ngx_module_t;
typedef struct ngx_conf_s ngx_conf_t;
typedef struct ngx_cycle_s ngx_cycle_t;
typedef struct ngx_pool_s ngx_pool_t;
typedef struct ngx_chain_s ngx_chain_t;
typedef struct ngx_log_s ngx_log_t;
typedef struct ngx_open_file_s ngx_open_file_t;
typedef struct ngx_command_s ngx_command_t;
typedef struct ngx_file_s ngx_file_t;
typedef struct ngx_event_s ngx_event_t;
typedef struct ngx_event_aio_s ngx_event_aio_t;
typedef struct ngx_connection_s ngx_connection_t;

ngx_uint_t ngx_pagesize;
ngx_uint_t ngx_pagesize_shift;
ngx_uint_t ngx_cacheline_size;

// #define NGX_LOG_STDERR 0
// #define NGX_LOG_EMERG 1
// #define NGX_LOG_ALERT 2
// #define NGX_LOG_CRIT 3
// #define NGX_LOG_ERR 4
// #define NGX_LOG_WARN 5
// #define NGX_LOG_NOTICE 6
// #define NGX_LOG_INFO 7
// #define NGX_LOG_DEBUG 8

// #define NGX_LOG_DEBUG_CORE 0x010
// #define NGX_LOG_DEBUG_ALLOC 0x020
// #define NGX_LOG_DEBUG_MUTEX 0x040
// #define NGX_LOG_DEBUG_EVENT 0x080
// #define NGX_LOG_DEBUG_HTTP 0x100
// #define NGX_LOG_DEBUG_MAIL 0x200
// #define NGX_LOG_DEBUG_STREAM 0x400

/*

  • do not forget to update debug_levels[] in src/core/ngx_log.c
  • after the adding a new debug level
    */

#define NGX_LOG_DEBUG_FIRST NGX_LOG_DEBUG_CORE
#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_STREAM
#define NGX_LOG_DEBUG_CONNECTION 0x80000000
#define NGX_LOG_DEBUG_ALL 0x7ffffff0

#ifndef NGX_PALLOC_H_INCLUDED
#define NGX_PALLOC_H_INCLUDED

#ifndef NGX_ALIGNMENT
#define NGX_ALIGNMENT sizeof(unsigned long) /* platform word */
#endif

#define NGX_OK 0
#define NGX_ERROR -1
#define NGX_AGAIN -2
#define NGX_BUSY -3
#define NGX_DONE -4
#define NGX_DECLINED -5
#define NGX_ABORT -6
#define NGX_INVALID_FILE -1
#define NGX_FILE_ERROR -1

#define ngx_errno errno
#define ngx_close_file close
#define ngx_close_file_n “close()”
typedef int ngx_err_t;
#define NGX_ENOENT ENOENT
#define ngx_delete_file_n “unlink()”

/*

  • 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)

#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)

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;
};

typedef struct ngx_pool_large_s ngx_pool_large_t;

struct ngx_pool_large_s {
ngx_pool_large_t *next;
void *alloc;
};

typedef struct {
u_char *last;
u_char *end;
ngx_pool_t *next;
ngx_uint_t failed;
} ngx_pool_data_t;

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;
};

typedef struct {
ngx_fd_t fd;
u_char *name;
ngx_log_t *log;
} ngx_pool_cleanup_file_t;

void *ngx_alloc(size_t size, ngx_log_t *log);
void *ngx_calloc(size_t size, ngx_log_t *log);

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);

#endif /* NGX_PALLOC_H_INCLUDED */

ngx_uint_t ngx_pagesize;
ngx_uint_t ngx_pagesize_shift;
ngx_uint_t ngx_cacheline_size;
#define ngx_free free
#define ngx_memzero(buf, n) (void) memset(buf, 0, n)
#define ngx_memset(buf, c, n) (void) memset(buf, c, n)
#define ngx_align_ptr(p, a)
(u_char *) (((uintptr_t) § + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))
#define ngx_delete_file(name) unlink((const char *) name)
#define ngx_delete_file_n “unlink()”

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

p = malloc(size);
if (p == NULL) {
    printf("malloc(%lu) failed\n", size);
}

printf("malloc: %p:%lu\n", p, size);

return p;

}

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

p = ngx_alloc(size, log);

if (p) {
    ngx_memzero(p, size);
}

return p;

}

//#define NGX_HAVE_POSIX_MEMALIGN 1
#define NGX_HAVE_MEMALIGN 1
#if (NGX_HAVE_POSIX_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) {
    printf("posix_memalign(%lu, %lu) failed\n", alignment, size);
    p = NULL;
}

printf("posix_memalign: %p:%lu @%lu\n", p, size, alignment);

return p;

}

#elif (NGX_HAVE_MEMALIGN)

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

p = memalign(alignment, size);
if (p == NULL) {
    printf("memalign(%lu, %lu) failed\n", alignment, size);
}

printf("memalign: %p:%lu @%lu\n", p, size, alignment);

return p;

}

#endif

//-------------------------------------------------------------------------------------------
//下面是从ngx_pcallo.c复制过来的内存池核心代码

static ngx_inline void *ngx_palloc_small(ngx_pool_t *pool, size_t size,
ngx_uint_t align);
static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);

ngx_pool_t *
ngx_create_pool(size_t size, ngx_log_t *log)
{
ngx_pool_t *p;

p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
if (p == NULL) {
    return NULL;
}

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);
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;

p->current = p;
p->chain = NULL;
p->large = NULL;
p->cleanup = NULL;
p->log = log;

return p;

}

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) {
        printf("run cleanup: %p\n", 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) {
    printf("free: %p\n", l->alloc);
}

for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
    printf("free: %p, unused: %lu\n", 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;
    }
}

}

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;

}

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);

}

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

return ngx_palloc_large(pool, size);

}

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);

}

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;

}

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

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;
}

large->alloc = p;
large->next = pool->large;
pool->large = large;

return p;

}

void *
ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
{
void *p;
ngx_pool_large_t *large;

p = ngx_memalign(alignment, size, pool->log);
if (p == NULL) {
    return NULL;
}

large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
if (large == NULL) {
    ngx_free(p);
    return NULL;
}

large->alloc = p;
large->next = pool->large;
pool->large = large;

return p;

}

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) {
        printf("free: %p\n", l->alloc);
        ngx_free(l->alloc);
        l->alloc = NULL;

        return NGX_OK;
    }
}

return NGX_DECLINED;

}

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

p = ngx_palloc(pool, size);
if (p) {
    ngx_memzero(p, size);
}

return p;

}

ngx_pool_cleanup_t *
ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
{
ngx_pool_cleanup_t *c;

c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
if (c == NULL) {
    return NULL;
}

if (size) {
    c->data = ngx_palloc(p, size);
    if (c->data == NULL) {
        return NULL;
    }

} else {
    c->data = NULL;
}

c->handler = NULL;
c->next = p->cleanup;

p->cleanup = c;

printf("add cleanup: %p\n", c);

return c;

}

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;
        }
    }
}

}

void
ngx_pool_cleanup_file(void *data)
{
ngx_pool_cleanup_file_t *c = data;

printf("file cleanup: fd:%d\n",
               c->fd);

if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
    printf(" \"%s\" failed\n", c->name);
}

}

void
ngx_pool_delete_file(void *data)
{
ngx_pool_cleanup_file_t *c = data;

ngx_err_t  err;

printf("file cleanup: fd:%d %s\n",
               c->fd, c->name);

if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {
    err = ngx_errno;

    if (err != NGX_ENOENT) {
        printf(" \"%s\" failed\n", c->name);
    }
}

if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
    printf(" \"%s\" failed\n", c->name);
}

}

#if 0

static void *
ngx_get_cached_block(size_t size)
{
void *p;
ngx_cached_block_slot_t *slot;

if (ngx_cycle->cache == NULL) {
    return NULL;
}

slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize];

slot->tries++;

if (slot->number) {
    p = slot->block;
    slot->block = slot->block->next;
    slot->number--;
    return p;
}

return NULL;

}

#endif

//-------------------------------------------------------------------------------------------
//下面是Main函数和内存池打印代码

void print_pool(ngx_pool_t *pool)

{

if (pool->large != NULL)

{

    printf("has large memory\n");

    for(ngx_pool_large_t* i = pool->large; i!=NULL; i = i->next)

    {

        printf("\t\tlarge next=0x%x\n", i->next);

        printf("\t\tlarge alloc=0x%x\n", i->alloc);

    }

    }

    int i=1;

    while(pool)

    {

        printf("pool=0x%x,index:%d\n", pool, i++);

        printf("\t\tlast=0x%x\n", (pool->d).last);

        printf("\t\tend=0x%x\n",(pool->d).end);

        printf("\t\tnext=0x%x\n",(pool->d).next);

        printf("\t\tfailed=%d\n",pool->d.failed);

        printf("\t\tmax=%d\n",pool->max);

        printf("\t\tcurrent=0x%x\n",pool->current);

        printf("\t\tchain=0x%x\n",pool->chain);

        printf("\t\tlarge=0x%x\n",pool->large);

        printf("\t\tcleanup=0x%x\n",pool->cleanup);

        printf("\t\tlog=0x%x\n",pool->log);

        printf("\t\tavailable pool memory=%d\n", pool->d.end-pool->d.last);

        printf("\n");

        pool=pool->d.next;

    }

}

void print_array(int *a,int size)

{

for(int i=0; i<size; i++)

{

    printf("%d,",a[i]);

}

printf("\n");

}

int main()

{

ngx_pool_t *pool;

int array_size = 1;

int array_size_large = 1024;

int page_size = getpagesize();//获得一页的大小

printf("page_size:%d\n", page_size);

printf("----------------------------\n");

printf("create a new pool\n");

pool = ngx_create_pool(1024, NULL);//创建一个大小为1024的内存池

print_pool(pool);

printf("----------------------------\n");

printf("alloc block 1 from the pool:\n");

int *a1 = ngx_palloc(pool, sizeof(int) * array_size);//分配第一块内存 用于创建数组

for (int i=0; i< array_size; i++)

{

    a1[i] = i+1;

}

print_pool(pool);

printf("----------------------------\n");

printf("alloc block 2 from the pool:\n");

int *a2 = ngx_palloc(pool, sizeof(int) * array_size);//分配第二块内存 用于创建数组,这个时候会创建第二个内存池节点

for (int i=0; i< array_size; i++)

{

    a2[i] = 12345678;

}

print_pool(pool);

printf("----------------------------\n");

printf("alloc large memory:\n");

printf("\t\tlarge next before=0x%x\n", pool->current->d.last);

int * a3 = ngx_palloc(pool, sizeof(int) * array_size_large);//由于大小超过了max的值 ngx_palloc中会调用ngx_palloc_large分配大块内存

printf("\t\tlarge next after=0x%x\n", pool->large);

for (int i=0; i< array_size_large; i++)

{

    a3[i] = i+1;

}

print_pool(pool);

print_array(a1,array_size);//分配的第一块内存块首地址

print_array(a2,array_size);//分配的第二块内存块首地址

print_array(a3,array_size_large);//分配的大内存块首地址

ngx_destroy_pool(pool);

return 0;

}

结果:

michael@SD-20220518ZLPG:~/test$ ./a.out
page_size:4096

create a new pool
memalign: 0x7fffd4595470:1024 @16
pool=0xd4595470,index:1
last=0xd45954c0
end=0xd4595870
next=0x0
failed=0
max=944
current=0xd4595470
chain=0x0
large=0x0
cleanup=0x0
log=0x0
available pool memory=944


alloc block 1 from the pool:
pool=0xd4595470,index:1
last=0xd45954c4
end=0xd4595870
next=0x0
failed=0
max=944
current=0xd4595470
chain=0x0
large=0x0
cleanup=0x0
log=0x0
available pool memory=940


alloc block 2 from the pool:
pool=0xd4595470,index:1
last=0xd45954cc
end=0xd4595870
next=0x0
failed=0
max=944
current=0xd4595470
chain=0x0
large=0x0
cleanup=0x0
log=0x0
available pool memory=932


alloc large memory:
large next before=0xd45954cc
malloc: 0x7fffd4595880:4096
large next after=0xd45954d0
has large memory
large next=0x0
large alloc=0xd4595880
pool=0xd4595470,index:1
last=0xd45954e0
end=0xd4595870
next=0x0
failed=0
max=944
current=0xd4595470
chain=0x0
large=0xd45954d0
cleanup=0x0
log=0x0
available pool memory=912

1,
12345678,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,
michael@SD-20220518ZLPG:~/test$

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/894674.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

揭秘亚马逊广告运作:了解逻辑,事半功倍的广告成功!

亚马逊广告的多重形式亚马逊为卖家提供了多种广告形式&#xff0c;用于在平台上展示并推广产品。以下是亚马逊广告的主要形式&#xff1a; 1.Sponsored Products&#xff1a; 这是常见的广告类型&#xff0c;允许产品在搜索结果和产品页面中显示。广告与自然搜索结果相似&…

23款奔驰GLE450豪华型桃木方向盘,提升方向盘握感

桃木是目前国内各级车型中最为主流的木饰&#xff0c;虽然看起来一样&#xff0c;但是多数低端车型中配备的并非实木&#xff0c;而是由聚酯材料制成的仿桃木。其实我们这里所说的“桃木”也并非我们所熟知的那个可以结桃子的果树&#xff0c;而是胡桃木或是核桃木。胡桃木原产…

算法通关村第八关——轻松搞定翻转二叉树

二叉树有很多经典算法题&#xff0c;今天我们就来看一下二叉树里的翻转问题。 力扣226,给了一棵二叉树&#xff0c;要将二叉树整体翻转。 分析&#xff1a;观察图中翻转前后的二叉树&#xff0c;我们不难发现&#xff0c;翻转过程中&#xff0c;只需要把每一个节点的左右子节点…

13. Vuepress2.x 部署站点的基础路径从配置文件中读取

收到需求&#xff0c;站点要部署到 非根路径 下&#xff0c;且将来会根据 版本号 区分不同的基础路径。需要从统一的文件中读取&#xff0c;方便其它 js 文件和 config.js 配置统一读取。 目录 docs\.vuepress\public\cfg\ 下新建文件 version.js&#xff0c;内容如下 const P…

cmake扩展(5)——file命令排除部分文件

在cmake中可以使用file命令获取需要的文件&#xff0c;并且支持正则/通配符&#xff0c;使用起来还是很方便的。 #语法file({GLOB | GLOB_RECURSE} <out-var> [...] [<globbing-expr>...])#example file(GLOB_RECURSE SOURCES "src/*.h" "src/*.cp…

如何计算 SDK 占用的 CPU 算力值(DMIPS)

什么是 DMIPS &#xff1f; 网上搜了些 DMIPS 的相关材料&#xff0c;知道它是用来评价 CPU 运算能力的一个指标。其中在知乎上有人介绍这个概念&#xff0c;是自动驾驶芯片性能常用的评价指标&#xff08;自动驾驶芯片性能评价指标:DMIPS,TOPS - 知乎&#xff09;。 如何计算…

CSS如何将浏览器文字设置小于12px

CSS如何将浏览器文字设置小于12px 使用transform: scale进行缩放 transform: scale(0.8);<div><p class"first">第一段文字</p><p class"second">第二段文字</p> </div>.first {font-size: 12px; }.second {font-si…

SeleniumIDE用例录制

1、录制回放方式的稳定性和可靠性有限 2、只支持 Firefox、Chrome 3、对于复杂的页面逻辑其处理能力有限 环境准备 Chrome 插件&#xff1a;https://chrome.google.com/webstore/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd Firefox 插件&#xff1a;Selenium IDE …

Java课题笔记~ SpringBoot简介

1. 入门案例 问题导入 SpringMVC的HelloWord程序大家还记得吗&#xff1f; SpringBoot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化Spring应用的初始搭建以及开发过程 原生开发SpringMVC程序过程 1.1 入门案例开发步骤 ①&#xff1a;创建新模块&#…

==和equals方法之间的区别,hashcode的理解

==和equals方法之间的区别 字符串有字符串常量池的概念,本身就推荐使用String s="字符串", 这种形式来创建字符串对象, 而不是通过new关键字的方式, 因为可以把字符串缓存在字符串常量池中,方便下次使用,不用遇到new就在堆上开辟一块新的空间 有一对双胞胎姐妹,晓苑…

[bug] 记录version `GLIBCXX_3.4.29‘ not found 解决方法

在使用mediapipe 这个库的时候&#xff0c;首次使用出现 GLIBCXX_3.4.29’ not found 错误&#xff0c; 看起来是安装mediapipe 的时候自动升级了 matplotlib 这个库&#xff0c;导致依赖的 libstd.so 版本不满足了&#xff0c;GLIBCXX_3.4.29 is an object from libstdc.so.…

万宾燃气管网监测解决方案,守护城市生命线安全

方案背景 城市燃气管网作为连接天然气长输管线与天然气用户的桥梁&#xff0c;担负着向企业和居民用户直接供气的重要职责。随着城市燃气需求的急剧增加&#xff0c;城市燃气管网规模日趋庞大&#xff0c;安全隐患和风险也随之增加。目前&#xff0c;我国燃气管网的运行仍存在…

spad芯片学习总结

一、时间相关单光子计数法TCSPC(Time correlated single photon counting) 1> 如果spad接收用单次发射、峰值检测会怎么样 首先spad是概率性触发的器件&#xff0c;探测到的概率远小于1&#xff0c;而且不仅接收信号的光子可以触发&#xff0c;环境光噪声一样会被spad接收到…

豪越智慧后勤助力医院后勤管理高质量发展

医院后勤管理是医院管理的重要组成部分&#xff0c;医院后勤管理水平直接影响了现代医院正常运行和医院的经济效益和医疗质量。随着社会的发展和市场环境的改变&#xff0c;医院后勤管理工作必须做出相应的调整&#xff0c;才能更符合市场需求&#xff0c;提升医院的竞争力。 近…

线性代数3,什么是向量 向量空间(草稿,建设ing)

列向量 行向量 4 什么是向量空间&#xff0c;向量的张成空间 域&#xff0c;组等概念 空间 向量空间 张成空间 6 线性代数 普通代数&#xff0c;是以单个的数为研究对象的数学 线性代数本质是以数组&#xff08;数组/向量&#xff1a;多个数为整体&#xff09;为基本对象的…

Matplotlib数据可视化(二)

目录 1.rc参数设置 1.1 lines.linestype取值 1.2 lines.marker参数的取值 1.3 绘图中文预设 1.4 示例 1.4.1 示例1 1.4.2 示例2 1.rc参数设置 利用matplotlib绘图时为了让绘制出的图形更加好看&#xff0c;需要对参数进行设置rc参数设置。可以通过以下代码查看matplotli…

一文科普,配资门户网是什么?

配资门户网是一个为投资者提供配资服务的平台。配资是指通过借用他人资金进行投资交易的一种金融操作方式。配资门户网作为一个线上平台&#xff0c;为投资者提供了方便、快捷的配资服务。 配资门户网提供了多种不同的配资方案&#xff0c;以满足不同投资者的需求。投资者可以…

广州华锐互动:奶牛难产原因及救治VR仿真实训系统

奶牛难产是一种常见的疾病&#xff0c;对奶牛的健康和生产造成很大的影响。为了解决这一问题&#xff0c;许多奶牛养殖场开始采用VR仿真技术来培训奶牛兽医&#xff0c;帮助学生更好地理解奶牛养殖的实际过程&#xff0c;提高他们的实践能力的教学方式。 VR技术开发公司广州华锐…

索引下推介绍

索引下推 介绍作用MySQL5.6之前MySQL5.6及以上版本举例说明 该语句的具体执行 MySQL 5.6之前MySQL 5.6之后判断方法总结 介绍 索引条件下推&#xff0c;也叫索引下推&#xff0c;英文全称‘Index Condition Pushdown’, 简称ICP。 作用 索引下推是MySQL5.6新添加的特性&#xf…

字节4面通过,我可以跟面试官要30K吗?

春招&#xff0c;秋招&#xff0c;社招&#xff0c;我们程序员的面试之路&#xff0c;是挺难的&#xff0c;过了HR&#xff0c;还得被技术面&#xff0c;小编在去各个大厂面试的时候&#xff0c;经常是通宵睡不着觉&#xff0c;头发都脱了一大把&#xff0c;还好最终侥幸能够入…