万里长征第一步, 设计一个内存管理器, 以及相关的一切.
我曾经做过一个内存池, 效率还可以, 没有做太大的测试, 等再优化一下我会把这份代码公开, 并请朋友做一些效率测试. 今天要做的, 却是一个更为广义的内存管理器. 也许有人会问, new 不是很好么 ? 可是我就是不喜欢new. 原因有很多.
1 效率, 2 定制. new 出来的内存除了分配效率不高外, 还有执行效率未必高. 呵呵, 有人会怀疑贫我在天方夜谭了吧?都tmd是内存, 难道你自己写的内存管理器能把内存条变成金的?? 对于这个问题, 我只想说下现在的cpu架构和 缓存一致性 原则. 有兴趣的朋友可以去看看滴了解下, 在这我就不赘述了. 有问题问度娘. 至于有什么不明白的可以沟通, 也许我的理解也有错误的地方或者说压根我就是错的. 至于定制, 我想实现多种内存管理方式来规避一些问题,比如: 有的地方会频繁的分配小块内存, 并造成内存碎片, 有的地方却不会产生碎片. 如果把这两处分配分别在不同的内存池中进行,就会把内存碎片控制在某一个内存池中, 而不会影响到其他的池.
基于以上两个原因, 我需要设计一个内存分配器. class IAllocator; 希望的用法是这样. 在每个 new 的地方, 我先调用一个函数 : IAllocator* GetAllocator();来获取一个当前的 IAllocator, 然后把这个值通过参数传递到 operator new 函数中, 以此来实际分配函数. 实现只需要用宏修改 new 为 new(GetAllocator())并实现一个全局的 operator new 的一参函数. 可是事情并不是我想的这样. 因为delete 不能调用一个重载了的operator delete. (除非在异常被触发, 这显然不是我们需要的.)
剩下的想法就是自己来实现一个宏. 因为我希望这个宏能够兼容 new 的原装行为, 而且也能满足实现自己想要的调用. 想来想去, 就做了以下的实现. 用五个宏来替换所有的 new , 也就是说原生的new操作符禁止使用.
分别是 NEW_(X), NEW_E(X,size), 分别对应 new T, new T[] 操作
DEL(X), DEL_E(X) 分别对应 delete p, delete [] p;
原因是 这样既可以方便使用原生的 new, delete. 也可以使用自定义的. 只需要在#define 的地方做出一点修改.
当然还必须适应debug模式下记录文件名和代码行的功能.
我现在给出一个分配器的接口.
class IAllocator
{
public:
IAllocator(){}
virtual ~IAllocator(){};
public:
virtual void* malloc(__int64 len, unsigned long flag = 0) = 0;
virtual void free(void* ptr, unsigned long flag = 0, __int64 = 0) = 0;
virtual SYS::INT GetLLen() = 0;//脏数据实现, 考虑是否添加
public:
static const unsigned int m_DefaultType = -1;//默认值待修改
};
这样就有了一个内存分配器的接口. 实现上分为两部分: 外部 和 内部.
外部打算用一些宏来实现, 内部实现自己的一些分配方式.
接下来的时间先完成外部的定义. 内部我已经实现了一个例子, 等完成了一并放出来.