Ngnix 源码学习----内存池的申请
来源:互联网 发布:json格式数据 编辑:程序博客网 时间:2024/06/05 08:30
这篇文章,主要是对代码的注释。就是对内存池的销毁,以及如何使用内存池的内存。如果 对内存的结构已经很了解,那么,对以下代码就很好理解了
////销毁内存池 基本都是链表的基本操作。voidngx_destroy_pool(ngx_pool_t *pool){ ngx_pool_t *p, *n; ngx_pool_large_t *l; ngx_pool_cleanup_t *c;///根据注册的ngx_pool_cleanup_s 来逐个销毁内存 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; } }}////充值内存池,先销毁,再重新分配内存voidngx_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); } } pool->large = NULL; for (p = pool; p; p = p->d.next) { p->d.last = (u_char *) p + sizeof(ngx_pool_t); }}/////这个方法就是 申请了内存后,///对内存的使用了。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); 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_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; 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);}////申请下一个内存块。static void *ngx_palloc_block(ngx_pool_t *pool, size_t size){ u_char *m; size_t psize; ngx_pool_t *p, *new, *current; psize = (size_t) (pool->d.end - (u_char *) pool); //计算pool大小 m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);////申请psize大小的内存 if (m == NULL) { return NULL; } new = (ngx_pool_t *) m; //给new。 new->d.end = m + psize;//在额外申一个等大小的内存 ,设置end 值 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; current = pool->current; for (p = current; p->d.next; p = p->d.next) { if (p->d.failed++ > 4) { current = p->d.next; } } p->d.next = new; pool->current = current ? current : 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(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;}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_tngx_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;}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;}/////注册cleanup的一个内存池分配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; ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c); return c;}voidngx_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; } } }}voidngx_pool_cleanup_file(void *data){ ngx_pool_cleanup_file_t *c = data; ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d", c->fd); if (ngx_close_file(c->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, ngx_close_file_n " \"%s\" failed", c->name); }}voidngx_pool_delete_file(void *data){ ngx_pool_cleanup_file_t *c = data; ngx_err_t err; ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s", c->fd, c->name); if (ngx_delete_file(c->name) == NGX_FILE_ERROR) { err = ngx_errno; if (err != NGX_ENOENT) { ngx_log_error(NGX_LOG_CRIT, c->log, err, ngx_delete_file_n " \"%s\" failed", c->name); } } if (ngx_close_file(c->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, ngx_close_file_n " \"%s\" failed", c->name); }}#if 0static 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
下面给几个图片以帮助大家理解。不是我画的
基本的内存数据结构
内存配图,很清晰了,都是链表的操作
看完之后,已经对ngnix的内存池的分配有很清晰的认识了,以后写个内存可以借鉴他的。哈哈,
更多文章欢迎访问:http://blog.csdn.net/wallwind
- Ngnix 源码学习----内存池的申请
- Ngnix 源码学习(4)----内存池的申请
- Ngnix 源码学习(3)----内存池结构
- ngnix源码分析----ngx_array_s 内存数组
- Ngnix学习
- ngnix学习
- ngnix学习
- 申请内存的函数
- 内存申请的释放
- 申请内存的问题
- ngnix:共享内存
- nginx源码学习----内存池
- nginx源码学习----内存池
- nginx源码学习----内存池
- nginx源码学习----内存池
- nginx源码学习----内存池
- nginx源码学习----内存池
- nginx源码学习----内存池
- #、##和可变参数宏__VA_ARGS__
- <转>UBUNTU终端SU认证失败解决
- iOS开发常用的开源库和示例
- OpenRTMFP/Cumulus Primer(8)CumulusServer主进程主循环分析
- iphone UIScrollView详解(转)
- Ngnix 源码学习----内存池的申请
- linux字符设备模型
- vmtools设置共享文件夹在linux的mnt/hgfs下却看不到文件夹的问题
- PlayBook应用开发系列讲座 - 使用Adobe AIR 2011
- 独立开发音乐播放器3
- hdu 4223 Dynamic Programming?
- Myeclipse9破解终于搞定了,找了很多都不行,无法自动生成System id 可以自动生成systemid 自动替换文件
- 替换数字金额为大写金额
- 第9周任务1(Complex类中的<<和>>运算符重载实现时间的输入和输出)