
C++11移植内存池
文章平均质量分 68
剖析并移植SGISTL二级空间配置器和nginx的内存池源码
林林林ZEYU
坚持
展开
-
501-nginx源码编译测试内存池接口函数功能
测试代码#include <ngx_config.h>#include <nginx.h>#include <ngx_core.h>#include <ngx_palloc.h>#include <stdio.h>#include <stdlib.h>#include <string.h>void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ng原创 2021-08-29 18:56:49 · 866 阅读 · 0 评论 -
500-nginx内存池(外部资源释放和内存池销毁)
举个例子相当于我们开辟了一大块内存,p指针指向一块堆内存的数据空间对象的成员变量占用外部的资源free只是把大块内存释放了,这个内存里的成员变量可能占用着外部资源,怎么释放???在释放大块内存之前,先执行一个函数,预置资源释放的函数,释放大块内存之前,把其他该释放的先释放。因为这个内存池是C语言写的,需要预置回调函数。如果是C++,会有析构函数。cleanup的作用我们来看,cleanup_s相当于大块内存的内存头信息,把释放资源的回调都组织起来在一个结构体里面。第一...原创 2021-08-29 13:19:02 · 444 阅读 · 1 评论 -
499-nginx内存池(重置函数和小块内存回收)
重置函数释放函数但是这个释放内存的函数仅仅是给大块内存调用的。为什么小块内存不用释放内存???nginx的小块内存是无法释放的,因为这个小块内存的分配都是通过last指针偏移的如果1和3分配出去了,正在使用,2不使用了,2怎么归还到小块内存里?在这里,标识空闲内存就使用了2个指针,last和end。不可能现在把2这块内存给拉进去空闲内存空间里面。小块内存不带回收的话,小块内存随着分配越来越大,系统的内存肯定是分配失败,这该怎么考虑???内存池重置函数两个for循环,第一个for循环在遍原创 2021-08-29 11:50:17 · 702 阅读 · 2 评论 -
498-nginx内存池(大块内存分配)
大块内存分配size>pool->max,无论如何,max的大小不会超过1个页面的,小于等于4095传入内存池的起始地址和申请的内存的大小我们从头开始解析下去首先, 定义了3个变量next相当于链表串起来,alloc保存大块内存的起始地址然后执行实际上就是调用malloc,开辟大块内存然后执行刚开始,这个large也是空指针,for循环不进去。我们往下看。ngx_pool_large_t也给小块内存池分配了,因为小块内存池的分配效率非常高,通过last..原创 2021-08-29 11:19:56 · 317 阅读 · 0 评论 -
497-nginx内存池(小块内存分配)
create_pool开辟指定大小的内存块。都是一块一块分配的。每个内存池都有一个头,第一个内存块的头部信息有详细。同一个颜色表示同一个变量的里面的具体内容。last指向的是可用内存的起始地址end指向的是可用内存的末尾地址current指向的是现在内存的起始地址现在这个内存块是可以分配内存的申请内存在nginx里有3个函数上面2个函数的区别是传入的参数,一个考虑内存对齐,一个不考虑内存对齐还有一个内存申请函数内存开辟完之后,会给内存清0剖析ngx_palloc如何从ngin.原创 2021-08-29 10:37:21 · 1083 阅读 · 0 评论 -
496-nginx内存池(palloc创建函数create pool)
nginx内存池(palloc创建函数)palloc.h第1个宏的名字意思是:能从池里分配的最大内存(4096字节)(4k)也就是说,对于nginx,小块内存和大块内存区分的界线是1个页面(4096)第2个宏的名字意思是:默认的池的大小(16k)第3个宏的名字意思是: 内存池内存分配的字节对齐数字第4个宏的名字意思是:内存池中最小的大小我们进去看看ngx_align函数这个似曾相识,和SGI STL的相似,作用是把内存的开辟调整到临近a(16)的倍数函数的接口内存池结构体第原创 2021-08-29 09:38:12 · 1086 阅读 · 1 评论 -
495-SGI STL二级空间配置器(reallocate内存扩容函数)
reallocate内存扩容或者缩容函数__p就是chunk块的起始地址,__old_sz是原先的内存块的大小,__new_sz是想要的新的内存块的大小通过一级空间配置器malloc开辟的,就调用底层的realloc通过二级空间配置器内存池开辟的还是在原来的元素位上。如果是在不同的元素位上,重新分配chunk块。考虑是扩容还是缩容两种情况...原创 2021-08-28 21:03:09 · 282 阅读 · 1 评论 -
494-SGI STL二级空间配置器(_S_chunk_alloc函数和内存池总结)
接下来我们看_S_chunk_alloc函数对具体内存块的分配nobjs都是20,这是写固定的数字。然后还传入我们申请的字节数。也就是chunk的个数和chunk的大小_S_chunk_alloc函数正常流程的内存分配我们一步一步来解析下去__total_bytes计算内存池的总字节数__bytes_left就是剩余的字节数因为初始化都是0,所以end-start=0就到else代码段里执行0右移4位还是0然后执行malloc了,按字节数开辟内存,对于8字节的大小来说,开辟了4.原创 2021-08-28 20:56:01 · 463 阅读 · 3 评论 -
493-SGI STL二级空间配置器(_S_refill函数)
_S_refill函数//负责把分配好的chunk块进行连接,添加到自由链表当中 static void* _S_refill(size_t __n);原创 2021-08-28 18:07:55 · 319 阅读 · 0 评论 -
492-SGI STL二级空间配置器(allocate内存分配)
内存池管理函数allocate函数传进去的参数 __n就是用户想开辟的内存的大小如果大于128字节,就不受内存池管理,通过malloc去(一级空间配置器)。如果小于等于128字节,就由内存池管理。假设我们现在要申请13字节的内存块,用__my_freelist_list局部变量指向16字节大小的数组的位置1下标我们看看函数定义的lock利用栈上对象出作用域自动析构的特点,lock出},就进行析构锁了。临界区代码段,通过锁控制保证线程安全,因为自由链表的增删改不是线程安全的,所以要原创 2021-08-28 11:42:45 · 284 阅读 · 0 评论 -
491-SGI STL二级空间配置器(重要的辅助接口函数)
重要的辅助接口函数_S_round_up 分析_S_round_up通过容器的空间配置器开辟内存的时候,申请的字节大小进行封装,上调至8的倍数ALIGN先进行类型强转 ALIGN-1,就是8-1=7,就是0111,再进行个按位取反~,1000,它是先把ALIGN转成unsignedint 4字节的,调整成4字节的,然后希望在按位与的时候,某个位置为的元素留下来,所以高位底下全是1。那么它是如何把1-8–》89-16–》16如果这个bytes是0的话,执行表达式后的结果还是0原创 2021-08-28 11:09:41 · 213 阅读 · 0 评论 -
490-SGI STL二级空间配置器(重要类型和变量定义)
我们看看这3个枚举_ALIGN:对齐8字节_MAX_BYTES:最大的字节数128_NFREELISTS:自由链表的个数16也就是说,对于二级空间配置器的内存池的实现:有一个数组空间,这个数组空间里面有很多元素,第一个是从8字节开始,第二个是从16字节开始,每一个都是以加8的方式来记录。128除以8=16个元素每个数组下标都是挂着1个自由链表。自由链表每个节点的大小和数组对应的大小是一样的。最大的是最后一个,128字节。如果大于128字节,就不会放在内存池来管理了。它认为大于128原创 2021-08-28 10:19:56 · 164 阅读 · 0 评论 -
489-剖析SGI STL空间配置器
不管是C的malloc free 还是C++的new delete,底层涉及内存管理调用的都是malloc,free,malloc和free是C的库函数。如果我们在应用场景中涉及小块内存的开辟和释放,短时间内调用的次数特别多,由于malloc和free在进行内存管理的时候相对来说底层实现是比较复杂的。对于小块内存频繁的分配和释放,如果我们一直使用malloc和free,会对我们的应用程序的运行在内存管理的效率降低,此时,我们就要使用内存池的设计,对小块内存的频繁分配和释放进行内存池的管理,提高应用程序的性原创 2021-08-28 09:53:08 · 404 阅读 · 0 评论