内存池原理
在嵌入式项目中很多时候要求在程序运行的时候不能调用malloc等内存分配的接口,要求在编译阶段就确定需要使用的内存大小,这时候就需要用的内存池来提前分配大块的内存,在代码中使用内存池分配内存。
内存池原理其实很简单,就是使用全局变量申请一块内存,然后基于这些全局变量的内存来进行内存分配和回收。
内存池的实现目前主流有两种:
- 连续内存的内存池
我们在实际分配内存的时候,因为内存大小不一,采用连续的内存池就是基于一块连续的内存去分配这些大小不一的内存,在回收的时候根据地址要做合并,使用这种内存的好处是配置简单,比较难造成内存浪费,缺点就是性能较差。
- 块内存池
该模型的内存池就是根据实际代码中内存分配的情况,申请多个全局变量当做不同块大小的内存池,每个内存池分割成单一块大小的内存,申请内存的时候根据内存块的大小从最匹配的内存块中获取一块。块内存池的优点是性能好,缺点是会造成一定的内存浪费。
代码
头文件
#ifndef _MEM_POOL_H_
#define _MEM_POOL_H_
#include "mempool_list.h"
#define MEM_LIST_NUMBER 10
int mempool_init(mem_list *_mem_lists,const size_t mem_list_num);
void* mempool_malloc(const size_t size);
void mempool_free(void* ptr);
void mempool_destory();
#endif
实现
#include "mem_pool.h"
mem_list* mem_lists[MEM_LIST_NUMBER] = {0};
int mempool_init(mem_list *_mem_lists,const size_t mem_list_num)
{
if(mem_list_num >MEM_LIST_NUMBER) {
return -1;
}
for(int i = 0;i<mem_list_num;i++) {
mem_lists[i] = &_mem_lists[i];
size_t offset = _mem_lists[i].block_size+sizeof(mem_node);
size_t block_num =_mem_lists[i].mem_size /offset;
char* ptr = (char*)mem_lists[i]->ptr;
for(int block_i = 0;block_i<block_num;block_i++) {
mem_list_insert_head(mem_lists[i],ptr,i);
ptr += offset;
}
pthread_mutex_init(&_mem_lists[i].mtx, NULL);
}
return;
}
void* mempool_malloc(const size_t size) {
mem_node* node = NULL;
for(int i = 0;i<MEM_LIST_NUMBER;i++) {
if(size<= mem_lists[i]->block_size) {
node = mem_list_pop(mem_lists[i]);
break;
}
}
node++;
return node;
}
void mempool_free(void* ptr) {
if(ptr == NULL) {
return ;
}
mem_node* node = (mem_node*)ptr;
printf("11 ptr:%p\n",node);
node--;
printf("22 ptr:%p\n",node);
mem_list_insert_tail(mem_lists[node,node->mem_list_index],node,node->mem_list_index);
return ;
}
void mempool_destory() {
return ;
}
**
完整源码下载地址:
**
https://download.csdn.net/download/len_yue_mo_fu/87864910