手写内存池以及原理代码分析【C语言】

本文详细介绍了内存池的概念、作用以及为何要使用内存池,主要针对堆区碎片化的问题。通过分析内存池的设计,包括使用链表管理和固定内存块的策略,展示了如何避免内存碎片。同时,文章提供了内存池的API实现,包括创建、销毁、重置内存池,以及分配和释放内存等操作。最后,推荐了阅读nginx内存池作为进一步学习的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内存池是对堆进行管理

当进程执行时,操作系统会分出0~4G的虚拟内存空间给进程,程序员可以自行管理(分配、释放)的部分就是mmap映射区、heap堆区,而内存池管理的部分就是用户进程的堆区。

为什么要用内存池?

内存池就是用来避免堆区出现碎片化

  • 避免频繁地分配和释放内存(防止堆区出现碎片化)

当客户端连接上服务端的时候,服务端会准备一部分的堆区用来做消息保留。当一个连接成功之后,服务器会在堆区为其分配一段属于这个连接的内存,当连接关闭之后,所分配的内存也随之释放。但是当连接量较大且过于频繁时,不可避免地对内存进行频繁的分配和释放。这会导致堆区出现小窗口,也就是堆区碎片化。

堆区出现碎片化会怎么样?

  • 长时间工作会出现不可查的BUG

  • 无法分配较大且整块的内存,malloc会返回NULL

内存池设计

场景:在一段很干净的堆区上,如何实现能避免内存碎片化的内存池?

第一:使用链表管理内存

使用链表将分配出来的一块一块内存在堆区连接起来,设置flag(是否被使用),让链表节点上的各段内存慢慢各自扩张。

单独使用链表会出现什么问题?

  • 内存块会被划分得越来越小,链表会变得越来越长,知道不能划分出更大得内存。

所以加入了固定内存的想法的设计

对于分配小段内存时,将小段内存进行固定划分,如下

  1. 16bytes

  2. 32bytes

  3. 64bytes

  4. 128bytes

  5. 256byts

  6. 512bytes

但是不同的固定小内存的分配的话就会出现以下问题:

1.查找慢

分配时查找

释放时候查找

2.块与块之间也会出现间隙

无法将块合并

小块回收麻烦

所以最后得出自定义固定小块和随机大块的内存池模型

内存池

内存池工作流程

内存池结构体

//内存池
struct mp_pool_s{

	size_t max;					
	
	struct mp_node_s *current;		//当前指向的小块内存区,链表结构
	struct mp_large_s *large; 		//大块内存

	struct mp_node_s *head[0];		//小块内存的头部
};

小块内存用单向链表串起来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值