65.9K
CodeProject 正在变化。 阅读更多。
Home

VMemPool - 虚拟内存池管理类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (18投票s)

2002年8月9日

CPOL

2分钟阅读

viewsIcon

159557

downloadIcon

3361

如果在服务器编码中处理相同大小的对象,VMemPool 为初学者展示了一个好方法。

引言

如您所知,new/delete 操作会占用大量 CPU 时间。 如果您使用服务器,则 CPU 时间非常重要。 如果将额外的内存添加到服务器,则服务器的可用内存大小将以线性方式增长。 但是,CPU 的行为并不相同(双 CPU 并不一定意味着单 CPU 情况下的两倍速度。)
因此,常见的服务器代码都有自己的高效内存管理系统。 VMemPool 是我的其中之一。

关于实现

CVMemPool 是泛型(模板)类,因为我假设客户端希望与 new/delete 类似的使用方式。 因此,使用 CVMemPool,您可以像使用普通指针一样进行编码。

CObj* p = new CObj;

p->do();

delete p;

CVMemPool 具有自己的“分配表”,使用循环队列实现,因此您可以使用 vmIsBadPtr 检查池中的指针是否有效。 您还可以使用 vmGetPoolInfo 检查池中分配了多少对象。

CVMemPool 有两个模板变量,class objTDWORD _dwPoolSizeT = 1000_dwPoolSizeT 是池的大小。 您可以使用此变量重新配置池大小。 objT 对您来说应该不重要。 如果缺少 objT 并且您有不同的类,请如下创建对象。

// suppose CVMemPool is like below. it's not real code.
template <DWORD _dwPoolSizeT = 1000>
class CVMemPool 
{ 
  ... 
};

class CObj1 : public CVMemPool<>
{
 ...
};

class CObj2 : public CVMemPool<>
{
 ...
};

CObj1 c1;
CObj2 c2; // it will share pool with c1 , it is not good. cos i need objT.

如您所知,当编译器看到最后一个实例化代码时,编译器会认为 c1 和 c2 具有相同的模板类布局,因此它只创建一个虚拟池(因为 CVMemPool<T,F>::ms_pMemPool 是静态的。)

用法

//make class in pool.
class CObj : public CVMemPool<CObj>
{
 ...
};

// and you can use it same like general new/delete code.
CObj* p = new CObj; // Pool is created, and allocation in first pool block.
CObj* p2 = new CObj; // second pool block will be used.

delete p; // first block will be freed.
delete p2; // second ,too.

性能

测试环境

P4 1.6GHz, 256MB 内存, Windows 2000 Professional, 发布可执行文件测试。
测试了两种情况
首先,CObj 的大小为 1,000 字节,循环 new 和 delete 10,000 , 20.000 ....
首先,CObj 的大小为 10,000 字节,循环 new 和 delete 10,000 , 20.000 ....
(n * 1,000 是错误的,n* 10,000 是正确的,对不起)结果如下。

我不能说这些结果完全正确,但我认为在服务器端或在某些 CPU 的客户端,CVMemPool 会比默认的堆操作(new/delete)更好。
在第二种情况下,我测试了 6,000 个或更多,但我无法在“堆”上看到结果,因为程序给出了致命错误 - 内存不足 - 当然,CVMemPool 运行良好且速度很快。 :)

我希望它能帮助你。 非常感谢!

修订历史

2002 年 8 月 14 日 - 初次修订

© . All rights reserved.