Nginx learning: memory pool
Recommended for you: Get network issues from WhatsUp Gold. Not end users.
The data structure of nginx management memory pool is ngx_pool_t. In ngx_request_t, the ngx_conf_t controlled ngx_pool_t.
A defined in nginx Ngx_palloc.h:
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 { u_char *last; u_char *end; ngx_pool_t *next; ngx_uint_t failed; } ngx_pool_data_t;
Last has been used at the end of the block of memory to the current, end points to the current block of memory at the end, next refers to a block of memory, nginx is using memory pool chain table.
typedef struct ngx_pool_large_s ngx_pool_large_t; struct ngx_pool_large_s { ngx_pool_large_t *next; void *alloc; };When the allocated memory pool size is more than NGX_MAX_ALLOC_FROM_POOL, a pointer to the memory pool to keep a copy of this structure. The benefits of doing so is to
struct ngx_pool_cleanup_s { ngx_pool_cleanup_pt handler; void *data; ngx_pool_cleanup_t *next; };
Save the need to clean up the data pointer and the corresponding cleanup function in this result, let the memory pool destruction
Two. The correlation function control memory pool
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);
2.1 note and Ngx_alloc.h void *ngx_alloc (size_t size, ngx_log_t *log); and void *ngx_calloc (size_t size, ngx_log_t *log) to distinguish
According to the definition:
ngx_alloc(size_t size, ngx_log_t *log) { void *p; p = malloc(size); 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; } void * ngx_calloc(size_t size, ngx_log_t *log)//initial the ngx_alloc { void *p; p = ngx_alloc(size, log); if (p) { ngx_memzero(p, size); } return p; }Ngx_alloc and ngx_calloc just simple encapsulation of alloc and calloc. Ngx_palloc is the control of the memory pool, meaning is completely different.
2.2 the significance of each function
ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log);//Create a pool of memory unit, nginx memory pool is connected with a list of the 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);//Memory alignment, interested can look at nginx is how do aligned, do a tricky, nginx visible on the processing of detail. 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;//Size setup cannot be more than 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);//Clear memory pool structure, here cleaning objects including cleanup, large and D. 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); } } for (l = pool->large; l; l = l->next) { ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc); if (l->alloc) { ngx_free(l->alloc); } } #if (NGX_DEBUG) /* * we could allocate the pool->log from this pool * so we cannot use this log while free()ing the pool */ 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 (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);//According to the literal reset, this function is a pool reset. 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);//Ngx_pool_t itself takes up a memory p->d.failed = 0; } pool->current = pool; pool->chain = NULL; pool->large = NULL; } void *ngx_palloc(ngx_pool_t *pool, size_t size);//A part from the allocated memory pool void * ngx_palloc(ngx_pool_t *pool, size_t size) { u_char *m; ngx_pool_t *p; if (size <= pool->max) { p = pool->current; do { m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);//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);//Failed to get a piece of memory pool, redistribution } return ngx_palloc_large(pool, size);//Failed to get the redistribution, a large memory pool } void *ngx_pnalloc(ngx_pool_t *pool, size_t size);//With the ngx_palloc difference is: ngx_pnalloc access memory will not consider the alignment situation. void * ngx_pnalloc(ngx_pool_t *pool, size_t size) { u_char *m; ngx_pool_t *p; if (size <= pool->max) { p = pool->current; do { m = p->d.last;//Get behind, without considering the 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); } return ngx_palloc_large(pool, size); } void *ngx_pcalloc(ngx_pool_t *pool, size_t size);//Distribution of the mgx_palloc memory is initialized 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; } static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);//Allocate a large block of memory 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(pool, sizeof(ngx_pool_large_t)); if (large == NULL) { ngx_free(p); return NULL; } large->alloc = p; large->next = pool->large;//put in the head??? pool->large = large; return p; } void *ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment);//Allocate a large block of memory, compared with ngx_palloc_large, increasing the alignment function. 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(pool, sizeof(ngx_pool_large_t)); 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);//Small memory with the destroy release, but the bulk memory free can be used to release. 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_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size);//A section of memory allocation and registration 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;//There may be further optimized, because data allocation failure, should be immediately free off the C share memory. } } else { c->data = NULL; } c->handler = NULL; c->next = p->cleanup;//put int header p->cleanup = c; ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c); return c; }
Three functions and documents related to the following, no longer tired. 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);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download
Posted by Brendan at February 22, 2014 - 11:35 AM