内存管理库
- jemalloc 内存管理,C 语言。
- tcmalloc 内存管理,C++。
- 在头文件中引入即可。
确定 block 的大小、不确定 block 的释放时间,如何设计内存池 ?
#include <stdio.h>
#include <stdlib.h>
#define MEM_PAGE_SIZE 4096
typedef struct mempool_s {
int block_size;
int free_count;
char *free_ptr;
char *mem;
} mempool_t;
int mp_init(mempool_t *m, int size) {
if (!m) return -1;
if (size < 16) size = 16;
m->block_size = size;
m->mem = (char *)malloc(MEM_PAGE_SIZE);
if (!m->mem) return -1;
m->free_ptr = m->mem;
m->free_count = MEM_PAGE_SIZE / size;
int i = 0;
char *ptr = m->free_ptr;
for (i = 0;i < m->free_count;i++) {
*(char **)ptr = ptr + size;
ptr += size;
}
*(char **)ptr = NULL;
return 0;
}
void mp_dest(mempool_t *m) {
if (!m || !m->mem) return ;
free(m->mem);
}
void *mp_alloc(mempool_t *m) {
if (!m || m->free_count == 0) return NULL;
void *ptr = m->free_ptr;
m->free_ptr = *(char **)ptr;
m->free_count --;
return ptr;
}
void mp_free(mempool_t *m, void *ptr) {
*(char **)ptr = m->free_ptr;
m->free_ptr = (char *)ptr;
m->free_count ++;
}
int main() {
mempool_t m;
mp_init(&m, 32);
void *p1 = mp_alloc(&m);
printf("1: mp_alloc: %p\n", p1);
void *p2 = mp_alloc(&m);
printf("2: mp_alloc: %p\n", p2);
void *p3 = mp_alloc(&m);
printf("3: mp_alloc: %p\n", p3);
void *p4 = mp_alloc(&m);
printf("4: mp_alloc: %p\n", p4);
mp_free(&m, p2);
void *p5 = mp_alloc(&m);
printf("5: mp_alloc: %p\n", p5);
return 0;
}
不确定 block 的大小,确定 block 的释放时间,如何设计内存池 ?
#include <stdio.h>
#include <stdlib.h>
#define MEM_PAGE_SIZE 4096
typedef struct mp_node_s {
char *free_ptr;
char *end;
struct mp_node_s *next;
} mp_node_t;
typedef struct mp_pool_s {
struct mp_node_s *first;
struct mp_node_s *current;
int max;
} mp_pool_t;
int mp_init(mp_pool_t *m, int size) {
if (!m) return -1;
void *addr = malloc(size);
mp_node_t *node = (mp_node_t*)addr;
node->free_ptr = (char*)addr + sizeof(mp_node_t);
node->end = (char*)addr + size;
node->next = NULL;
m->first = node;
m->current = node;
m->max = size;
return 0;
}
void mp_dest(mp_pool_t *m) {
if (!m) return ;
while (!m->first) {
void *addr = m->first;
mp_node_t *node = (mp_node_t*)addr;
m->first = node->next;
free(addr);
}
return ;
}
void *mp_alloc(mp_pool_t *m, int size) {
void *addr = m->current;
mp_node_t *node = (mp_node_t*)addr;
do {
if (size <= (node->end - node->free_ptr)) {
char *ptr = node->free_ptr;
node->free_ptr += size;
return ptr;
}
node = node->next;
} while (node);
addr = malloc(m->max);
node = (mp_node_t*)addr;
node->free_ptr = (char*)addr + sizeof(mp_node_t);
node->end = (char*)addr + m->max;
node->next = m->current;
m->current = node;
char *ptr = node->free_ptr;
node->free_ptr += size;
return ptr;
}
int main() {
mp_pool_t m;
mp_init(&m, MEM_PAGE_SIZE);
void *p1 = mp_alloc(&m, 16);
printf("1: mp_alloc: %p\n", p1);
void *p2 = mp_alloc(&m, 32);
printf("2: mp_alloc: %p\n", p2);
void *p3 = mp_alloc(&m, 64);
printf("3: mp_alloc: %p\n", p3);
void *p4 = mp_alloc(&m, 128);
printf("4: mp_alloc: %p\n", p4);
void *p5 = mp_alloc(&m, 256);
printf("5: mp_alloc: %p\n", p5);
mp_dest(&m);
}
内存池的好处
- 内存池是内存块的管理组件。
- 首先要分配整块内存, 然后为整块内存制定一些策略,如果内存不够,就再分配一块。
- 避免了小块的内存分配,避免了频繁地向操作系统申请内存。
- 避免了长期运行出现的内存碎片。