NGINX(二)内存池
ngxin中为了加快内存分配的速度,引入了内存池, 大块申请, 减少分配次数, 小块分割, 极大的提高了内存申请速度, 另外一个用途就是省去了很多内存管理的任务,因为这里没有提供内存释放的功能,也就是说在pool中分配的内存,只有pool被销毁的时候才能释放掉,真正的还给系统, 因此全局的pool存储的都是一些静态的不会变动的数据, 而会变动的数据都会单独创建一个pool, 用完之后释放掉pool, 也就实现了集中申请集中释放, 肯定会有浪费内存的现象存在, 和提高运行速度比起来, 浪费点内存还是可以接受的.
基本数据结构
typedef struct ngx_pool_cleanup_s ngx_pool_cleanup_t;
typedef struct ngx_pool_large_s ngx_pool_large_t;
typedef struct ngx_pool_s ngx_pool_t;struct ngx_pool_cleanup_s {ngx_pool_cleanup_pt handler;void *data;ngx_pool_cleanup_t *next;
};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;/*缓存chain链表, 重新申请时从这里直接取出*/ngx_chain_t *chain;/*大块内存链表, 很简单直接分配内存, 挂接到链表结束为止*/ngx_pool_large_t *large;ngx_pool_cleanup_t *cleanup;ngx_log_t *log;
};
创建内存池
创建一块内存池, 首先会申请一块用户指定的大小, 即size大小, 但是size很显然最小要为sizeof(ngx_pool_t)大小, 申请内存开头放置ngx_pool_t结构体, 剩余的用作内存池内存, 提供给用户使用, 如下图示
|----------------> size <--------------------|
|-----------------|--------------------------|
p ngx_pool_t p->d.last p->d.end
ngx_pool_t *
ngx_create_pool(size_t size, ngx_log_t *log)
{ngx_pool_t *p;/*申请size大小内存*/p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);if (p == NULL) {return NULL;}/*用户使用内存要除去sizeof(ngx_pool_t)大小*/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;/*设置当前使用的pool为p,因为就一个*/p->current = p;p->chain = NULL;p->large = NULL;p->cleanup = NULL;p->log = log;return p;
}
申请内存
分配带内存对齐的内存, 一般用于结构体, 加快访问速度.
void *
ngx_palloc(ngx_pool_t *pool, size_t size)
{u_char *m;ngx_pool_t *p;/*size大小决定进行小块内存分配还是大块内存分配方案*/if (size <= pool->max) {/*取出当前pool*/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);
}
重新分配一个pool
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);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;/*由于只使用了ngx_pool_data_t数据结构, 因此这里实际可使用的内存只去除了sizeof(ngx_pool_data_t)大小, 跟创建时sizeof(ngx_pool_t)不同*/m += sizeof(ngx_pool_data_t);m = ngx_align_ptr(m, NGX_ALIGNMENT);new->d.last = m + size;current = pool->current;/*遍历链表最后位置, 但current并不一定到最后, 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;
}
关于大块内存申请是直接向系统申请, 释放的时候直接返回给系统, 没有什么好讲的.
转载于:https://www.cnblogs.com/ourroad/p/4838362.html
NGINX(二)内存池相关推荐
- nginx的内存池及内存管理
nginx对内存的管理是由自己实现的内存池结构ngx_pool_t来完成,本文主要讲nginx的内存管理. nginx对内存管理涉及到四个文件:src/core/ngx_palloc.h.src/co ...
- Nginx源码分析-内存池
本文转自淘宝平台http://www.tbdata.org/archives/1390,不是为了夺他人之美,只是觉得写得很好,怕淘宝万一删掉就找不到了,放在这里保存一下.大家可以直接链接过去,他们那个 ...
- 这是我见过最详细的Nginx 内存池分析
一,为什么要使用内存池 大多数的解释不外乎提升程序的处理性能及减小内存中的碎片,对于性能优化这点主要体现在: (1)系统的malloc/free等内存申请函数涉及到较多的处理,如申请时合适空间的查找, ...
- Nginx源码分析:核心数据结构ngx_cycle_t与内存池概述
nginx源码分析 nginx-1.11.1 参考书籍<深入理解nginx模块开发与架构解析> 核心数据结构与内存池概述 在Nginx中的核心数据结构就是ngx_cycle_t结构,在初始 ...
- nginx内存占用高---内存池使用思考
nginx内存占用高-内存池使用思考 问题现象 nginx top 进程 虚拟内存 200G 实际内存5G 和 CDN 平台相比要高很多 排查思路 使用pmap -p 进程号,发现从系统角度确实 有分 ...
- nginx源码分析—内存池结构ngx_pool_t及内存管理
本博客( http://blog.csdn.net/livelylittlefish)贴出作者(阿波)相关研究.学习内容所做的笔记,欢迎广大朋友指正! Content 0.序 1.内存池结构 1.1 ...
- nginx源码分析—内存池结构ngx_pool_t及内存管理(精辟)
Content 0.序 1.内存池结构 1.1 ngx_pool_t结构 1.2其他相关结构 1.3 ngx_pool_t的逻辑结构 2.内存池操作 2.1创建内存池 2.2销毁内存池 2.3重置内存 ...
- nginx源码分析之内存池实现原理
建议看本文档时结合nginx源码: 1.1 什么是内存池?为什么要引入内存池? 内存池实质上是接替OS进行内存管理,应用程序申请内存时不再与OS打交道,而是从内存池中申请内存或者释放内存到内存池, ...
- Nginx源码阅读笔记-内存池的设计
2019独角兽企业重金招聘Python工程师标准>>> nginx的内存池设计的比较简单了,一个内存池中分为两个部分: 超过max大小的内存分配,走大块内存分配,这部分内存管理由ng ...
- 【Nginx 源码学习】内存池 及 优秀案例赏析:Nginx内存池设计
文章目录 关于设计内存池之我的想法 内存池案例 malloc 底层原理 jemalloc && tcmalloc Nginx内存池设计 基础数据结构 源码分析 ngx_create_p ...
最新文章
- linux删除zlib无法远程,linux zlib默认装在哪里
- Python-OpenCV 杂项(二)(三): 鼠标事件、 程序性能的检测和优化
- dede服务器建站_建站就是这么简单(内容系统管理CMS篇)
- Java多线程 - 线程组
- 《转》VC++多线程编程
- 机器人炒饭小块头一一_一罐好饭,智能机器人炒饭出好味道,小块头坚守本心匠心制作!...
- 基于PHP的Google Voice 短信API
- 港股区块链板块持续上行,火币科技涨超50%
- Zabbix 服务器性能指标参考(学习笔记十七)
- vim编辑python_Python3基础知识——Vi/Vim编辑器的使用,大神们都在用的
- 23种设计模式(九)对象创建之原型模式
- Linux系统管理初步(六)设置计划任务
- 单片机技术及应用:基于proteus仿真的c语言程序设计,单片机的C语言程序设计与应用:基于Proteus仿真(第4版)...
- 龙卷风袭击广东致6死215伤 广州停
- MySQL实现跨库join查询
- python如何制作地图热力图
- macbook重装系统 选择方案_超详细的mac重装系统教程
- Python小记(一):import和from。。。import区别?
- 查询Mysql版本号的两种方法
- 20届icoding 实验1
热门文章
- python调用C++
- doc转docx文件会乱吗_【转】帮你解决docx转换为doc文档的乱码问题
- 蓝桥杯2015年第六届C/C++省赛B组第一题-奖券数目
- CSS 实现盒子水平垂直居中
- Android Studio - xml布局文件不显示代码怎么办?
- Android-【报错】java.lang.ClassCastException: .MainActivity cannot be cast to java.lang.Runnable
- L1-012 计算指数 (5 分)—团体程序设计天梯赛
- C语言课程2——我们交流的工具:Coding.net
- Android中resource参数变量使用
- MySQL数据库(五)