WinCE的内存泄露

来源:互联网 发布:xp 保存网络用户密码 编辑:程序博客网 时间:2024/05/20 03:44

原文地址:http://blog.csdn.net/norains/article/details/5276668

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

 

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

 

[cpp] view plaincopy
  1. {   
  2.   std::map <DWORD,DWORD> mpTmp;   //..........................(1)  
  3.   for(int i = 0; i < 1024 * 100; i ++)   
  4.   {   
  5.    mpTmp.insert(std::make_pair(i,i));   
  6.   }   
  7.   
  8.   mpTmp.clear();                        //............................(2)  
  9. }                                            //............................(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,只要你使用了堆,并且数据量够大,那么问题同样会出现。
  
  我们可以试试这个代码:

[cpp] view plaincopy
  1. {  
  2. const DWORD MAX_ALLOCATE = 1024 * 100;  
  3.  TCHAR **pBuf = new TCHAR * [MAX_ALLOCATE];  
  4.   
  5.  for(DWORD i = 0; i < MAX_ALLOCATE; ++ i)  
  6.  {  
  7.    pBuf[i] = new TCHAR [100];  
  8.  }  
  9.   
  10.  for(DWORD i = 0; i < MAX_ALLOCATE; ++ i)  
  11.  {  
  12.   delete [] pBuf[i];  
  13.  }  
  14. }  

  
  这段只是采用new进行分配的代码,问题依然如前所示。
  
  截止到本文完稿为止,我还是没有找到解决的方法,唯有看着那白白耗费的资源束手无措。根据经验推测,产生这问题很可能是因为WinCE 5.0的内存管理机制,但我目前没有WinCE 6.0的平台可供测试,所以也无法确定。
  
  最后,列出我的测试平台,在以下平台的测试都会出现如文中所提到的现象:
  
1. TCC7901, WINCE 5.0
2. AU1200, WINCE 6.0


0 0
原创粉丝点击