热门关键字:  ubuntu  分区  函数  Fedora  linux系统进程

当前位置 :| 主页>Linux教程>编程开发>C++>

用C++实现对内存的管理

来源: 作者: 时间:2008-05-30 Tag: 点击:


  例1:

template <class SuperHeap>
class SizeHeap {
 union freeObject {
  size_t sz;
  double _dummy; //对齐所需
 };
public:
 void * malloc(const size_t sz) {
  //添加必要的空间
  freeObject * ptr = (freeObject *)SuperHeap::malloc(sz + sizeof(freeObject));
  //存储请求的大小
  ptr->sz = sz;
  return ptr + 1;
 }
 void free(void * ptr) {
  SuperHeap::free((freeObject *) ptr - 1);
 }
 static size_t getSize (const void * ptr) {
  return ((freeObject *)ptr - 1)->sz;
 }
};

  SizeHeap是怎样实现一个实用的层,并挂钩于它基类的malloc与free函数的最好示例,它在完成一些额外的工作之后,把修改好的结果返回给使用者。SizeHeap为存储内存块大小,分配了额外的内存,再加上适当的小心调整(指union),尽可能地避免了内存数据对齐问题。不难想像,我们可构建一个debug堆,其通过特定模式在内存块之前或之后填充了一些字节,通过检查是否模式已被保留,来确认内存的溢出。事实上,这正是HeapLayers的DebugHeap层所做的,非常的简洁。

  让我们再来看看,以上还不是最理想的状态,某些系统已经提供了计算已分配内存块大小的原语(此处指操作符,即前述的分配算符),在这些系统上,SizeHeap实际上只会浪费空间。在这种情况下(如Microsoft Visual C++),你将不需要SizeHeap与MallocHeap的衔接,因为MallcoHeap将会实现getSize:

struct MallocHeap {
 ... 与上相同 ...
 size_t getSize(void* p) {
  return _msize(p);
 }
};

  但似乎还有一些不足之处。想一想,我们是在统计时钟周期,如果一个系统的malloc声明了内存的块大小将存储在实际块之前的一个字中,那将会怎样呢?在这种情况下,SizeHeap还是会浪费空间,因为它仍会在紧接着系统已植入的块后存储一个字。此处所需的,只是一个用SizeHeap的方法实现了getSize的层,但未挂钩malloc与free。这就是为什么HeapLayers把前面的SizeHeap分成了两个,见例2:

  例2:

template <class Super>
struct UseSizeHeap : public Super {
 static size_t getSize(const void * ptr) {
  return ((freeObject *) ptr - 1)->sz;
 }
protected:
 union freeObject {
  size_t sz;
  double _dummy; //对齐所需
 };
};

template <class SuperHeap>
class SizeHeap: public UseSizeHeap<SuperHeap>{
 typedef typename
 UseSizeHeap<SuperHeap>::freeObject
 freeObject;
public:
 void * malloc(const size_t sz) {
  //添加必要的空间
  freeObject * ptr = (freeObject *)SuperHeap::malloc(sz + sizeof(freeObject));
  //存储请求的大小
  ptr->sz = sz;
  return (void *) (ptr + 1);
 }
 void free(void * ptr) {
  SuperHeap::free((freeObject *)ptr - 1);
 }
};

[NextPage]

 现在,SizeHeap就会正确地添加UseSizeHeap层,并利用它的getSize实现了,而UseSizeHeap也能通过其他配置来使用--这是一个非常优雅的设计。

  一个实用的示例:FreelistHeap

  到目前为止,我们还处于一个准备的阶段,只有架构,还不知怎样利用这些层来编写一个高效专用的内存分配算符,也许一个比较合适的开发步骤可如下所示:

  ·收集有关程序为每种内存块大小进行分配次数的信息。

  ·为最经常请求的大小(在此称为S),维持一个私有、逐一链接的列表。
 
  ·对S的内存分配尽可能地从列表中返回内存,或者从默认分配算符中返回(在分层架构中,从上级层中)。

  ·对S大小内存块的释放,把内存块放回至列表中。

最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册
栏目列表