栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c/c++linux后台开发学习笔记 3.1.2 内存池原理与实现

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c/c++linux后台开发学习笔记 3.1.2 内存池原理与实现

内存池的作用

减少内存碎片,使服务器能长时间运行而不出现内存不够的情况

内存池使用场景

1)一个连接一个内存池,连接存在时内存池只分配内存,不释放内存。连接断开时把整个内存池释放。(如果我们手写内存池,只推荐这种场景)
2)一个进程一个内存池,进程退出时才释放。这种情况不推荐手写,推荐使用谷歌的tcmalloc

内存池原理

内存分大块和小块,内存池先分配大块(node),再在大块中分配小块。内存池的一些状态本身也保存在大块之中。如果要分配的内存本来就是大块(large),则另行分配,全都存在一个链表中,

内存池的实现
//注意mp_large_s 本身分配在node的数据块中
struct mp_large_s {
	struct mp_large_s *next;
	void *alloc;
};

struct mp_node_s {
	unsigned char *last; //next free memory
	unsigned char *end;  //end of block (not inclusive)
	struct mp_node_s *next; 
	size_t failed;       // 内存分配失败的次数(失败很多次意味着很可能整块都用完了)
};

struct mp_pool_s {
	size_t max;
	struct mp_node_s *current;
	struct mp_large_s large;
	struct mp_node_s head[0]; //第一个node必须分配在pool之后的内存里
};


failed:当前节点分配内存失败的次数,越大则表示当前节点越有可能满
current:指向下一个最有可能有空余空间的节点,如果当前current节点的fail数大于一个阈值,则把current指向它的下一个节点
在分配块内存时注意以32字节对齐

#define MP_ALIGNMENT 32

#define mp_align(n, alignment) (((n)+(alignment-1)) & ~(alignment-1))
#define mp_align_ptr(p, alignment) (void *)((((size_t)p)+(alignment-1)) & ~(alignment-1))

以这种方式分配内存

	struct mp_pool_s *p;
	int ret = posix_memalign((void **)&p, MP_ALIGNMENT, size + sizeof(struct mp_pool_s) + sizeof(struct mp_node_s));
	if (ret) {
		return NULL;
	}
接口
struct mp_pool_s *mp_create_pool(size_t size);
void mp_destory_pool(struct mp_pool_s *pool);
void *mp_alloc(struct mp_pool_s *pool, size_t size);
void *mp_calloc(struct mp_pool_s *pool, size_t size);
void mp_free(struct mp_pool_s *pool, void *p);
具体实现
void *mp_alloc(struct mp_pool_s *pool, size_t size) {

	unsigned char *m;
	struct mp_node_s *p;

	if (size <= pool->max) {

		p = pool->current;

		do {
			
			m = mp_align_ptr(p->last, MP_ALIGNMENT);
			if ((size_t)(p->end - m) >= size) {
				p->last = m + size;
				return m;
			}
			p = p->next;
		} while (p);

		return mp_alloc_block(pool, size);
	}

	return mp_alloc_large(pool, size);
	
}

其他函数略

参考资料

零声教育c/c++ linux开发3.1.2

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/664318.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号