简介

MemProof(内存清道夫)是AutomatedQA出品的一款非常不错的检测内存泄漏和资源泄漏的免费调试工具,适合于WIN32平台下使用DELPHI/C++ BUILDER开发的应用程序。

利 用它可以方便的查找出 一些忘记释放的指针以及资源。它通过在调试模式下运行目标程序,监视程序的创建和释放操作,以达到检测资源泄漏的效果。监测过程中它会根据资源类型计数, 每次创建后增加计数,释放则递减计数,最后程序结束根据计数即可判断出资源的泄漏。

MemProof的原作者是Atanas Stoyanov,后加盟了AutomatedQA公司,他目前是大名鼎鼎的AQTIME软件的主力开发者。MemProof已经很久没有更新了,作者在AutomatedQA的官方网站上也推荐大家使用AQTIME(http://www.automatedqa.com/products/aqtime/memproofusers.asp),因为AQTIME包含了MemProof的所有功能,并且拥有很多MemProof所不具备的特性,如:更好的COM支持,结合MSDN获 取帮助,平台测试等等。虽然有这么多好处,但是AQTIME毕竟是收费的商业软件,价格不 菲,而且体积相对庞大。对于我来说,更愿意选择MemProof。轻佻的体积,简单的操 作,还是免费的(这条最关键~~)。当然,对于大的企业用户来说,AQTIME也是个非常不错的选择。

使用方法

l 下载

官方网站上的最新版本为 (Build 0.950 July 19, 2004)

下载地址:http://www.automatedqa.com/products/memproof/index.asp

l 安装

MemProof是一个绿色软件,下载完成后解压,运行MemProof.exe即可。

l 准备

MemProof要求目标程序带有完整的调试信息。打开工程选项(Project-Options)

1、 Compiler面板

l 去掉Optimization(代码优化)选项

l 选择Stack Frames(为所有过程函数强制生成调用堆栈)选项

l 选择Debug information (在DCU文件中生成调试信息)选项

l 选择Use Debug DCUS(编译时链接带有调试信息的VCL DCU文件)选项

2、 Linker面板

l 选择Detailed(生成完整的MAP文 件,包含模块、单元、过程等地址信息)选项

l 选择Include TD32 debug info(将调试信息生成到可执行文件)选项

该选项会导致可执行文件体积增大,但不会影响运行效率以及内存占用, 建议在正式发布时不要带上该选项。

l 开始

一切准备就绪,现在可以开始调试了。

下面是用于调试的一段测试程序:

新建一个空白工程,在OnCreate事件中加入以下代码:

procedure TForm1.FormCreate(Sender: TObject);

begin

TFont.Create; //创 建一个TFONT对象,但不释放

CloseHandle(0); //关 闭一个不存在的句柄

end;

再根据上面的介绍设置好工程选项。打开MemProof:

Resources – 资源的类型,包括Error(错误)、Pointers(指针)、Memory(内存)、GDI(画布资源)、User(系 统对象)、Kernel(核心对象)、Registry(注册表)。

Resources Count – 资源数目,Current#代表当前数目,Peak#代表峰值数目

Resources Size – 资源大小,Current#代表当前大小,Peak#代表峰值大小

选择File-Open 打开要调试的 执行文件,再选择Run-Run 开始运行,再正常退出目标程序,如果有资源泄漏MemProof会自动打开Resources Details面板:

MemProof共列出5个内存泄漏,我们可以看到每个内存泄漏都有详细的调用栈情况,以及相对应的源码位置。

有时它会提示我们找不到对应的源码,这是应为没有指定源码搜索路径 的原因。MemProof有两个位置可以设置源码搜索路径,一个在Configure- Search Directories,一个在Projects-Search Directories。前者是设置全局路径,后者是设置当前路径。一般建议在前者中设置DELPHI的VCL以及共用库代码的路径,后者 设置工程本身源码的路径。MemProof还为用户提供了快捷搜索VCL源 码路径的按钮Get Default for ,使用这个按钮可以快捷的获取DELPHI的Libray Path(有的用户 安装了VC覆盖了默认调试工具选项,所以有可能得到的是VC的Libray Path,这种情况可以直接到DELPHI的Libray Path中去拷贝即可)。

另外MemProof还可以记录上次的测试结果方便用户做比较,以及过滤等功能。

如果需要测试动态连接库,可以选择Project-Parameters,在Host Applications中 选择主体程序,如果需要带命令行,则在Parameters中输入命令行,然后就可以开始测试了,和DELPHI中调试的方法是一样的。

MemProof不支持Attach Process的 调试方式,这是一个不足的地方。

使用其实非常简单,一看就明白了,下面介绍些调试中的经验技巧。

技 巧

l 渐进式测 试,从最易发现的错误开始解决

一个大型的软件可能会有 很多泄漏或者错误,这个时候可以渐进式的来测试,第一次测试可以直接运行后立即退出,检测在加载的过程中是否存在泄漏,然后逐一更正。再分功能模块进行测 试,比如只针对某个功能进行操作,然后退出检测该模块是否存在泄漏,如果存在,更正。最后再进行整体测试。这样可以避免一些关联性错误导致重复测试,而且 可以节省测试时间,可以使测试更有针对性。

l 分模块测 试,从单个的模块开始解决

和上一条原则一样,为了 缩小测试面。在Projects的Moudle Configers中 选择测试的模块,开始每次只选择一个模块针对性测试,最后再选择所有模块测试。

注意:不要选择一些如:Ole32.dll、kernel32.dll等系统模块。

l 错误优 先,发现错误与泄漏并存时,优先解决错误

测试过程中,

代表错误,这些错误往往是由于错误的使用系统API导 致,如:释放不存在的句柄,访问权限不够的资源,传递了错误的调用参数等。这些错误往往会导致代码没有按照预计的方式运行,触发一些内存泄漏。所以,需要 优先修正这些位置。

l 系统资源 优先,发现有GDI、User、Kernel、Registry等存在泄漏时优先 解决

系统资源泄漏往往是由于窗体、画布等资源 没有及时释放,这些错误非常明显,而且这种错误往往会带有很多的Pointers、Memory泄漏,所以,优先修正。

经 验

l 经过实际 证明,下列错误是可以忽略的

1、 VirtualAlloc(00000000,4096,4096,64) VirtualAlloc kernel32.dll

这是有名的4096字节内存泄漏问题,任何使用DELPHI的VCL编写的WIN32程序都会存在,这是由 于在Classes单元中的MakeObjectInstance方法中使用VirtualAlloc分配了4096字节的内存,并没有释放。 这不是BUG,不释放是有原因的,请参考这篇文章:

http://www.thedelphimagazine.com/samples/1328/article.htm

2、OpenFileMapping

OpenFileMapping(4,0,”SMBuffer”) 导致的错误是由于BDE数据库引擎激活时,尝试OpenFileMapping和Sql Monitor建立链接, 但是当Sql Monitor未运行时,这个mapping 并不存在,所以会导致错误。这个错误已经被VCL所捕获处理。所以可以忽略。

3、 LoadCursor

VCL并不是完美的,有时运行程序出现很多LoadCursor错误也可以忽略。

4、 其他

还有更多的关于DELPHI和C++Builder本身导致的内存泄漏可以参见:

http://www.automatedqa.com/support/leaksd6.asp

l 发现泄漏 的位置在VCL单元中的时候,不要去考究VCL的 代码,找到调用栈中涉及到的外部单元去检查。相信VCL吧,绝大多数情况些它是不会导致内存 泄漏的。

缺 点

MemProof尽管非常优秀,同 样存在不少缺陷。如上面提到的不能Attach Process,这样就不能够调试ISAPI、服务程序等;还有,当程序由于访问保护内存、或强制结束进程等原因导致非正常退出时,MemProof将不会有任何结果报告;另外,MemProof的机制决定它不可能实现远程调试;最后,MemProof是个免费性质的软件,在帮 助支持方面做得不够,连一个像样的帮助都没有,同类的商业软件BoundCheker在这方面 做得非常不错,每个错误都可以在帮助中得到详细的解释,MemProof的这个缺点导致新 手不容易上手。

总结

关于MemProof就介绍到这里了。 总之,瑕不掩瑜,MemProof依然是广大DELPHI/C++BUILER爱好者的开发利器。

MemProof教程的更多相关文章

  1. AQTime教程(1)

    AQTime教程 1 简介 AQTime和MemProof都是AutomatedQA旗下的产品,AQTime比MemProof提供了更丰富强大的功能.该产品含有完整的性能和调试工具集,能够收集程序运行 ...

  2. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  3. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  4. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  5. Angular2入门系列教程4-服务

    上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...

  6. Angular2入门系列教程1-使用Angular-cli搭建Angular2开发环境

    一直在学Angular2,百忙之中抽点时间来写个简单的教程. 2016年是前端飞速发展的一年,前端越来越形成了(web component)组件化的编程模式:以前Jquery通吃一切的田园时代一去不复 ...

  7. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  8. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  9. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

随机推荐

  1. Oracle基础 (十二)数学函数

    数学函数: ABS(n):求绝对值 ),) FROM DUAL; --获取15的绝对值 结果:, BITAND(X,Y):返回X,Y进行位与(AND)的运算结果 ,), BITAND(,), BITA ...

  2. 进程控制块的task_struct结构

    >进程控制块 在linux中进程信息存放在叫做进程控制块的数据结构中,每个进程在内核中都有⼀个进程控制块(PCB)来维护进程相关的信息,Linux内核的 进程控制块是task_struct结构体 ...

  3. 转: 通过不到100行Go代码打造你自己的容器

    备注:这个文章讲容器,讲的比较的浅显易懂.推荐,前期入行者看. 转: http://www.infoq.com/cn/articles/build-a-container-golang?utm_sou ...

  4. sqlserver跟踪

    本文以实际应用为目的,不在理论方面深究 1.打开跟踪器 或 2.新建跟踪-事件选择-列筛选器,HostName默认不显示,需勾选“显示所有列”,如果希望只跟踪某一客户端,可按下面的设置HostName ...

  5. Table of Contents - Spring

    The IoC container Spring 容器 属性注入 & 构造注入 Bean 实例的创建方式 p-namespace & c-namespace 集合属性的注入 作用域 延 ...

  6. js实现全屏

    详细内容请点击 1.window.open方式 第一种: 在已经打开的一个普通网页上,点击“全屏显示”,然后进入该网页对应的全屏模式.方法为:在网页的<body>与</body> ...

  7. list笔记总结

    1.list是一个复合的复制函数,可以将一个数组一次赋给多个变量.我们常用以下语句遍历一个数组. $arr = array('东','男','西','北'); while(list($k,$v)=ea ...

  8. Part 14 Mathematical functions in sql server

    Part 29 Mathematical functions in sql server

  9. 安装包安装服务,点修复出现的错误”Error 1001:指定的服务已存在“ 解决办法

    安装项目下,右键视图->自定义操作,出现安装.提交.回滚.卸载四个文件夹,右键安装,添加自定义操作,选择安装的服务为输出文件 右键安装输出文件->在condition->Not (I ...

  10. Linux下DNS服务器的基本搭建

    技术交流群:286866978 安装与配置 1. 装载光驱 2. 卸载光驱 3. 将安装包放在合适的文件夹并解压(有的更换光盘需要重新装载) 4. 安装 5. 重定向配置文件 6. 配置named.c ...