WinCE的内存泄露

//=====================================================================
//TITLE:
// WinCE的内存泄露
//AUTHOR:
// norains
//DATE:
// Thursday 28- January-2010
//Environment:
// WINDOWS XP
// WINDOWS CE 5.0
//=====================================================================

在WinCE的环境下大家都使用过STL,单不知道大家有没有发现,这里有个致命的问题。如果容器的数据量比较大,会导致无法释放内存资源。不信?我们来看一下下面这个测试代码:

{ std::map <DWORD,DWORD> mpTmp; //..........................(1) for(int i = 0; i < 1024 * 100; i ++) { mpTmp.insert(std::make_pair(i,i)); } mpTmp.clear(); //............................(2) } //............................(3)

这个代码简单到只要学过STL的都知道是咋回事。意思无外乎是不停地往map容器插入数值,完成之后通过clear删掉。外面的{}是定死了mpTmp的作用域,让mpTmp执行到{}之外后会自动调用析构函数。

代码没什么,我们来看看实际的运行情况。

首先是在WinXP环境,内存监控我们直接采用任务管理器就好了。

  1).程序执行到代码(1)
  
  这时候的内存占用量截图如下:
  
  
  
  2).程序执行到代码(2)
  
  此时.clear()函数尚未执行,只是刚刚完成数值的插入。内存的耗用如下:


  
  
  很明显,内存有显著的上涨。
  
  
  3).程序执行到代码(3)
  
  此时已经调用了clear函数,内存占用量如下:


  
  由此可见,内存已经释放,基本上回到了分配前的大小。
  
  
  那么接下来我们看看在WinCE下的情况。代码执行的步骤和在WinXP相同,但监视内存的工具采用Windows CE Remote Performance Monitor。
  
  因为该工具是使用曲线图来表示,为了更方便观看,所以我们直接在曲线图中表示代码执行的步骤:


  
  
  是不是很诡异?没错,你没有看错!在调用了clear之后,内存占用根本就没有降低,还是保持之前的水准。即使mpTmp生存期已过,调用了析构函数,所分配的内存依然没有释放!
  
  也许你还想进一步查看程序究竟是哪块内存没有释放完毕,打算祭出Remote Heap Walker来定位查看,但诡异的事情发生了:你在列表中根本就找不到你正在调试的这个测试程序!
  
  为什么我说是数据量大的时候,资源是无法释放呢?你可以尝试一下,将示例中的循环次数改为1024。你会发现,一切都正常了,资源能释放了。
  
  相同的问题,不仅在map存在,其实在string也会有。即使你采用的是推荐的swap方式,在数据量暴多的时候,依然无法正确释放。
  
  实验和推测进行到这里,可能大家会有这么一种直觉:微软的STL库有问题!一开始,我也是这么想的。因为我用的是VS2005,所以又拿了VS2008的STL试着来尝试一下,发现结果依然如此。
  
  也许到了这里,矛头大家可能还是指向STL。但实际上,即使你不是使用STL,只要你使用了堆,并且数据量够大,那么问题同样会出现。
  
  我们可以试试这个代码:
  {   const DWORD MAX_ALLOCATE = 1024 * 100;    TCHAR **pBuf = new TCHAR * [MAX_ALLOCATE];       for(DWORD i = 0; i < MAX_ALLOCATE; ++ i)    {    pBuf[i] = new TCHAR [100];    }       for(DWORD i = 0; i < MAX_ALLOCATE; ++ i)    {    delete [] pBuf[i];    }   }
  
  这段只是采用new进行分配的代码,问题依然如前所示。
  
  截止到本文完稿为止,我还是没有找到解决的方法,唯有看着那白白耗费的资源束手无措。根据经验推测,产生这问题很可能是因为WinCE 5.0的内存管理机制,但我目前没有WinCE 6.0的平台可供测试,所以也无法确定。
  
  最后,列出我的测试平台,在以下平台的测试都会出现如文中所提到的现象:
  
1. TCC7901, WINCE 5.0
2. AU1200, WINCE 6.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值