技术开发 频道

让我生不如死的Windows CE内存泄漏

二. 什么是Windows CE内存泄露

   虽然Windows CE有许多方法来管理系统内存的运行,但还是有可能发生内存错误的。Win32编程中常见内存错误:①内存分配错误;②使用未初始化的内存;③内存泄露;④使用已经释放的内存资源。

(1)什么是内存泄漏

   内存泄漏是指程序在运行过程中申请的内存,在程序结束时没有被释放。我们常说的内存泄漏是指堆内存的泄漏,堆内存是指程序从堆中分配的。一般来说,应用程序是使用从堆中分配到一块内存,使用完后程序必须负责相应的释放该内存块。否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。

   一般来说,在所有时刻Windows CE内存管理器都知道进程所拥有的物理内存和虚拟内存。然而,如果进程分配内存时但由于Bug而无法释放内存(内存泄漏),内存管理器就可能无法了解这些已分配的内存,也无法重新访问这些内存,而必须等到进程退出时回收内存。但需要特别注意的是,同样的程序在Window XP平台上可能没有什么问题,但在缺乏内存的Windows CE平台,经过长时间运行该程序可能会内存耗尽而导致系统重启,这是我在经过几个生不如死的通宵达旦测试后得到的宝贵经验和教训。

   因此,内存泄漏引发的性能失常完全不同于程序错误,这些问题很难通过调试器对代码进行单步调试加以解决。对于将会在某时刻退出的桌面应用程序,较小的内存泄漏是可以承受的,因为退出进程将把占用的所有内存返还给操作系统。但对于长时间运行的嵌入式系统,则通常需要确保绝对没有内存泄漏。

(2)常见的内存泄漏原因

   常见的内存泄漏有这几种原因:①Windows CE内存碎片。②在局部堆申请的堆只增加不会马上减少,直到程序退出。③程序运行时分配物理内存,当程序使用完后,这些物理内存仍然被占用,直到系统内存不足时分页内存交换到分页文件中,然后才释放掉其占用的物理内存。④Windows CE内存管理的缺陷。

   总而言之,内存泄漏产生的主要原因是保留了却不再使用的内存空间。Windows CE虽然有自动管理内存的功能,但内存泄漏也是不容忽视,它往往是破坏嵌入式系统稳定性的重要因素。


三. 如何检测和处理内存泄漏?

   如何查找引起内存泄漏的原因,一般有两个步骤:第一是安排有经验的编程人员对代码进行走查和分析,找出内存泄漏发生的位置。第二是使用专门的内存泄漏测试工具进行测试。

(1)代码走读检测内存泄漏

   通常在怀疑发生内存泄漏之后,第一步是要弄清楚泄漏了什么数据和引起了什么泄漏。一般说来,一个正常的系统在其运行稳定后其内存的占用量是基本稳定的,不应该是无限制的增长的。根据这样的基本假设,我们持续地观察系统运行时使用的内存的大小,如果内存的大小持续地增长,则说明系统存在内存泄漏。

   内存泄漏可通过代码走读来发现和定位,也可以用专用的工具来测试和定位。实际上,对于内存泄漏,代码检查有时能比采用任何技术解决方案更快地找到问题所在。预防内存泄漏的唯一方法就是要求程序员在程序结束时,必须将每个申请的内存都释放。

(2)使用工具检测内存泄漏

   一旦知道确实发生了内存泄漏,就需要更专业的工具来查明为什么会发生泄漏。在这个时候,我们通常需要使用一些开销较低的工具来监控和查找内存泄漏。查找内存泄漏的工具很多,最常用的释放工具就是dmalloc和mpatrol,这些工具提供了记录并检查所有内存分配的调试版堆栈,从而有利于分析内存泄漏和悬挂指针。

   检测内存泄漏的关键是要能截获住对分配内存和释放内存的函数的调用,当截获住这两个函数,我们就能跟踪每一块内存的生命周期。比如,每当成功的分配一块内存后,就把它的指针加入一个全局的list中;每当释放一块内存,再把它的指针从list中删除。这样,当程序结束的时候,list中剩余的指针就是指向那些没有被释放的内存。哪么,最简单的内存泄漏检测方式就是截获住这些指针。

   总的来说,无论那种方式,我们都需要认真检查应用程序任何内存分配调用的返回代码,因为在Windows CE中比在桌面版本的Windows中有更多的机会导致内存分配失败,从而会导致内存泄漏。
 

0
相关文章