A simple memory allocation algrithim
来源:互联网 发布:傻黑的淘宝店 编辑:程序博客网 时间:2024/05/22 14:32
Purpose
Too frequent memory operation, such as malloc() and free(), can downgrade application performance. In order to improve the memory allocation performance, eliminate the impact of memory malloc() and free() operation, a customized memory allocation algorithm is introduced.
This algorithm is not for suitable for large memory allocation environment.
Basics
The basic idea of this algorithm is to reduce the alloc/free times; so a large block of memory is pre-allocated, and when a memory malloc() is required from application, the memory will be allocated from these pre-allocated memory blocks.
To implement this algorithm, a memory block will be spitted into a few fixed-size slots; slots size is aligned with power of 2, for example: 32,64,128,256,512,1K,2K, and so on. The slot size of a same block is same, different block can have different slot size.
Free slots with same size are organized as a link; these slots may located in different blocks. A global variable is used to point to the header of this chain.
So when allocate request is coming, return the free header slot, and header move next; when free request is coming, put the return slot at the header, and adjust header pointer correspondingly.
All slots have fixed size and the size cannot be changed, and there is no split or merge operation on any slots.
When there is no free slot to use, a new memory block will be allocated, and immediately split into fixed-size slots, and put to the header.
And this is the detail slot structure:
API
/**
* create a memory pool instance
*
* @param flag
* @return memory pool pointer, used for mempool_alloc(void * pool, size_t size), and mempool_free(void * pool, void * ptr)
*/
void * mempool_new(unsigned int flag);
/**
* alloc a memory space
*
* @param pool, the memory pool returned from a mempool_new
* @param size, the memory size to be allocated, its value must be 1 <= size <= (1*1024*1024 - 16) bytes
* @return memory pointer.
*/
void * mempool_alloc(void * pool, size_t size);
/**
* free a memory block.
*
* @param pool, the memory pool returned from mempool_new
* @param ptr, memory pointer to be freed, it must be a value returned from previous mempool_alloc call with same pool instance
*/
void mempool_free(void * pool, void * ptr);
Data Structure & Code
Compiled with gcc on Linux x86_64 platform.
Memory pool data structure
/** * MEMPOOL_MAGIC used to check this is a valid mempool instance. */#define MEMPOOL_MAGIC "MEMP"/** * Valid memory size [16=2**4, 1M=2**20] */#define MEMPOOL_MINSLOT 5#define MEMPOOL_MAXSLOT 20/** * forward declaration */static int find_slot_type(size_t size);/** * memorypool data structure */typedef struct { char magic[4]; // MEMPOOL_MAGIC unsigned int id; // random magic number struct mem_slots_t { void * freeslot; // free slot links } mem_slots[32]; unsigned int flag; // flag} mem_pool_t;
mempool_new
/** * Create memory pool instance * * @return pool pointer, used for future alloc/free */void * mempool_new(unsigned int flag){ mem_pool_t * mempool = (mem_pool_t *)malloc(sizeof(mem_pool_t)); if (mempool == NULL) { D("ERROR: cannot allocate memory for memory pool.\n"); return NULL; } memset(mempool, 0, sizeof(mem_pool_t)); memcpy(mempool->magic, MEMPOOL_MAGIC, 4); mempool->id = random(); mempool->flag = flag; return mempool;}
mempool_alloc
void * mempool_alloc(void * pool, size_t size){ if (pool == NULL) return NULL; mem_pool_t * mempool = (mem_pool_t *)pool; if (memcmp((char *)(mempool->magic), MEMPOOL_MAGIC, 4) != 0) { D("ERROR: invalid memory pool pointer at 0x%x\n", pool); return NULL; } // max memory size cannot exceed 1M Bytes. int slottype = find_slot_type(size); if (slottype < MEMPOOL_MINSLOT || slottype > MEMPOOL_MAXSLOT) { D("ERROR: allocate memory size (%d) is out of scope\n", size); return NULL; } void * slot = NULL; if (mempool->mem_slots[slottype].freeslot == NULL) { // there is no free slottype, alloc new memory block size_t slotsize = 1 << slottype; int pagesize = getpagesize(); size_t blocksize = slotsize <= pagesize ? pagesize : (slotsize <= 32*1024 ? 32*1024 : slotsize); void * block = malloc(blocksize); if (block == NULL) { D("ERROR: cannot allocate memory for memory block.\n"); return NULL; } D("INFO: allocate a new memory block size %d\n", blocksize); // allocate slottype in the block int i; for (i = 0; i < blocksize/slotsize; i++) { slot = block + slotsize * i; if (i != blocksize/slotsize - 1) // set next slot *(void **)slot = slot + slotsize; else *(void **)slot = mempool->mem_slots[slottype].freeslot; *(unsigned int *)(slot + 8) = 0; // set size *(unsigned int *)(slot + 12) = ~mempool->id; // set free flag } mempool->mem_slots[slottype].freeslot = block; } // return the first slot in freeslot list slot = mempool->mem_slots[slottype].freeslot; *(unsigned int *)(slot + 8) = size; *(unsigned int *)(slot + 12) = mempool->id; // set busy flag mempool->mem_slots[slottype].freeslot = *(void **)(mempool->mem_slots[slottype].freeslot); return slot + 16;}
mempool_free
void mempool_free(void * pool, void * p){ if (pool == NULL || p == NULL) return; mem_pool_t * mempool = (mem_pool_t *)pool; if (memcmp((char *)(mempool->magic), MEMPOOL_MAGIC, 4) == 0) { if (*(unsigned int *)(p - 4) == mempool->id) { unsigned int size = * (unsigned int *)(p - 8); int slottype = find_slot_type(size); // put p back into freeslot list *(void **)(p - 16) = mempool->mem_slots[slottype].freeslot; *(unsigned int *)(p - 4) = ~mempool->id; *(unsigned int *)(p - 8) = 0; mempool->mem_slots[slottype].freeslot = p - 16; } else { D("ERROR: invalid memory pool magic at 0x%x\n", pool); } } else { D("ERROR: invalid memory pool pointer at 0x%x\n", pool); }}
TO DO NEXT
To support multi-threads environment.
To support memory block free operation.
- A simple memory allocation algrithim
- Memory Allocation
- Out of memory on a 23040016-byte allocation.的原因
- android Out of memory on a xxx-byte allocation问题
- Android Out of memory on a 5200288-byte allocation.解决方法
- Out of memory on a 11111-byte allocation
- a simple function for memory dumping
- memblock -- a simple memory management module
- Memory allocation with strings
- DomUs and memory allocation
- Windows Memory Allocation Limitations
- Advanced Memory Allocation
- memory allocation manager
- Advanced Memory Allocation
- Dynamic memory allocation example
- C++: Custom memory allocation
- Kernel Memory Allocation
- Memory Allocation of C++
- 判断字符串是不是回文
- 软件设计模式 --状态模式
- 文章标题
- 服务器降级特技
- 固定导航栏
- A simple memory allocation algrithim
- java类里面不可以做逻辑运算,输出
- 如何在 Linux 上使用 GNU sed
- 一个人也要生活的精彩——懒人焖饭
- jQuery 基础DOM和CSS操作
- 鼠标事件的继承操作
- Android之调用摄像头拍照和从相册中选择照片
- Jsp/servlet的声明周期
- Oracle事务的执行1