首页 > 代码库 > 分配内存

分配内存

  1. 面向对象;
  2. 初始化内存池、申请内存、释放内存三个操作;
  3. 尽量小的复杂度,优先优化时申请内存时的复杂度;
  4. 加入单元测试和性能测试

面向对象

技术分享?

基本操作

首先,内存池直接返回真实的内存指针,进而无法在代码执行过程中对内存段的位置进行调整,所以空余空间可能很大,但被切开、四散的情况是存在的。这里不考虑这样的情况,需要实现的操作如下:

  • 初始化内存池:直接使用 new 申请一大段空间作为内存池;

  • 申请内存:若长度足够,则从内存池中选择指定长度的连续未使用段返回,并标记该段已使用;否则返回 NULL;

  • 释放内存:查询 ptr 是否是标记的,若是则回收,将该段标记为未使用,并返回 true;若否则返回 false。

首先简单点,看释放内存的操作。使用一个 used[position] 的字典,记录所有指针对应的内存段的大小;释放时直接查询 used 字典,若存在 ptr 指针,则处理,否则直接返回 false。

这里说的处理,即将该段内存由“使用中”标记为“未使用”,并从 used 字典中删除,而并不需要对数组清零(节约时间)。 另外,如果该段内存左右有其他空余的内存段,需要进行合并,为下一次申请大内存做准备。

而申请内存时,最优的操作是找到恰好大于等于当前需要长度的未使用内存段并返回,同时标记该段为“使用中”,内存段长度大于需求长度则进行切分,同样将剩下的部分作为“可使用”的内存段。

如下图所示,内存池一共有 16 个字节。依次申请了 4 个字节、2 个字节、2 个字节和 4 个字节的内存,内存池占用如下图所示:

技术分享?

分配内存