最近做stm32的开发,涉及到内存管理,自己按照官方实例简单移植的fatfs和和内存池。我的使用场景很简单,直接开辟数组即可,使用的时候从数组里分配。没啥说的。
但是无意中看了看nginx的内存池实现,觉得不错。仔细看了看,网上的描述已经很详细,大家可以详细看看,我会在后面附上有链接地址。另外github上有完整源码,c语言实现,比较简单明了,简单修改就可以使用。我只是做点补充性记录。
我要补充的内容是关于几个结构体的说明:
//回调函数结构体
struct ngx_pool_cleanup_s
{
ngx_pool_cleanup_pt handler;//回调函数
void *data;//外部资源
ngx_pool_cleanup_t *next;//下一个回调函数结构体
};
这个结构体,描述的是关于外部特殊资源的,这个结构提本身是在内存池里申请,并且其中外部资源data指针对应的内存也在内存池里申请,但是不保证一定要紧挨着。也就是说没有必要单独free这个结构,只要free所在内存池模块就可以了。
typedef struct ngx_pool_large_s ngx_pool_large_t; //大内存结构
struct ngx_pool_large_s
{
ngx_pool_large_t *next;//下一个大内存结构
void *alloc;//指向大块内存空间的指针
};
这个结构体,描述的是关于大内存资源申请的,这个结构提本身是在内存池里申请,但是其中alloc指针对应的内存却不在内存池里申请,所以销毁的时候需要特别对待下,需要直接free。在别人的描述中也说了:
“
对于被置于大块内存链,也就是被large字段管理的一列内存中的某块进行释放。该函数的实现是顺序遍历large管理的大块内存链表。所以效率比较低下。如果在这个链表中找到了这块内存,则释放,并返回NGX_OK。否则返回NGX_DECLINED。
由于这个操作效率比较低下,除非必要,也就是说这块内存非常大,确应及时释放,否则一般不需要调用。反正内存在这个pool被销毁的时候,总归会都释放掉的嘛!”
对于以上说法,我觉得还是应该释放单独free大内存块,因为即使对应的内存池释放了,也就是说struct ngx_pool_large_s对应的结构释放了,但是这个结构成员alloc指向的空间并没有释放。alloc对应的空间并不在内存池上,他是在外面,所以需要单独free。关于效率的问题可以使用hash表,组成二维结构,或者其它高效方式。
//内存池的数据块
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;//大内存结构链表,将申请超过max大小的内存块链入
ngx_pool_cleanup_t *cleanup;//对外部资源进行清理结构的链表
ngx_log_t *log;//日志信息
};
ngx_pool_data_t这个结构可以认为是内存池的头部,struct ngx_pool_s 结构是内存池完整描述。他们是在某一个内存池模块里紧挨着的。而上面说的外部特殊资源和大内存资源都在这个结构有里挂着,可以认为是访问外部资源和大内存资源的入口。
好了,到此吧。
下面是两个链接:
淘宝出品
https://blog.csdn.net/a987073381/article/details/52337635 csdn网友
阅读(1524) | 评论(0) | 转发(0) |