使用FastMM4结合View CPU避免内存泄漏

Added by 王坚, last edited by 王坚 on 四月  01 2006   (view change) 
Labels: (None) 



Add Labels   
Enter labels to add to 
this  page:
  
Tip: Looking 
for  a label ?  Just start typing.   
  

关键字:FastMM, Delphi, 内存泄漏, View CPU。
阅读前提: 有Delphi基础,关注本地代码和内存管理。

内存泄漏经常出现在本地代码中,特别是多线程和发生异常的情况下,这时候在delphi环境下,FastMM4就特别有用。

FastMM4是非常高效可靠的内存管理器,用来替代久久不更新的borland内存管理器是最好的。地址:http:
// sourceforge.net/projects/fastmm/

调试过程如下:

1 .打开FastMM4的调试功能,首先在自己的project里把FastMM4放在最前面,例如:

  FastMM4,
  Main 
in   ' Main.pas '
{MainForm}
,
再修改FastMM4Options.inc,打开全调试模式。例:
{$define FullDebugMode}

也可以在project中定义编译常量:FullDebugMode。同时把FastMM_FullDebugMode.dll拷贝到编译后生成的可执行程序所在目录。

再要打开内存泄漏报告:EnableMemoryLeakReporting。一般情况下是缺省打开的。

这样就打开了全调试模式,如果发生内存泄漏将会生成报告文件,如果在IDE运行的时候还会弹出一个对话框显示。报告文件类似:kicoy_MemoryManager_EventLog.txt

2 .报告文件由两部分组成,并且是每次运行append。

第一部分是泄漏的详细内容,将每个没释放的内存块详细信息显示出来。例:

A memory block has been leaked. The size 
is 28   
{一个28字节的内存块在程序结束后没有被释放}
{这个内存块在分配的时候的调用堆栈,也就是Call Stack,可以清楚看出调用函数的次序。如果是系统dll则还有相应的函数名。}
Stack trace of when 
this  block was allocated ( return  addresses):
4028E7
4030EC
406649
412365
41236E
411DD3
426B45
427236
42888C
{这个内存类型,如果是字符串string或TObject继承的对象则会显示名称。}
The block 
is  currently used  for  an  object  of  class : Unknown
{将内存块头256个字符显示出现,作为内容提示。}
Current memory dump of 
256  bytes starting at pointer address 107BDD8:
第二部分是总结性内容,例:
{这个小型内存块泄漏的报告,如果有大型内存块泄漏则会加一行专门提示大型内存块泄漏。}
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):
{21-28字节的内存块泄漏,未知类型一个}
21   -   28  bytes: Unknown x  1
Note: Memory leak detail 
is  logged to a text file  in  the same folder  as   this  application. To disable  this  memory leak check, undefine  " EnableMemoryLeakReporting " .

有了这份报告只不过了解到内存泄漏存在,但是哪里没释放就还需要更进一步地调查。

调查的目标有:

1 .内存块分配在哪个函数里哪段代码。

这个在报告里可以结合内容和调用堆栈来看。前256个字节可以进行分析,推测分配者,调用堆栈就直接指出了分配函数,不过是一些地址,不能直接知道函数名和代码段。这时候就需要在delphi ide环境下查看二进制内存映像了,就是View CPU功能。

在设定断点并停下后,可以View CPU,在菜单View
=> Debug Window => CPU  快捷键:Ctrl + Alt + C

View CPU Window:

正中就是内存映像,而且源码也相应地标注好了,左边列的地址就是内存报告中的Call Stack中的地址,翻页找到所对应的代码就知道哪里分配内存了。

2 .检查释放内存的地方是否被调用,可以用日志或断点来调试,如果压根就没有释放内存那就补上代码,如果有却没有执行则检查一下执行条件是否正确,如果断点没起作用很可能是因为代码永远不会被执行(死代码)。

这要靠经验和调试,基本上借助IDE和内存报告就可以很好地防止内存泄漏。同时要加强测试用例,争取在测试用例中能遍历到所有的代码和大部分关键功能,这样内存泄漏报告就会更准确一点。

fastmm每次在程序关闭后就会根据情况生成内存泄漏报告,如果没有弹出内存泄漏警告则恭喜你,内存管得很好。

现在总算不用羡慕虚拟机代码自动回收内存了,本地代码的内存管理也不是两眼一抹黑了,这是可以精确控制的,一切尽在掌握中。

另:

1 .内存管理不是GC自动回收内存,而是检查是否有泄漏。

2 .windows系统的内存泄漏是无法检查的,仅限于应用程序内部,不过检查出系统泄漏也没办法,只能等更新了。

3 .检查泄漏后要自己去检查代码补齐内存释放,报告并不能做这事。

------
www.kicoy.com

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
上次在盒子上用了可以加快Delphi2005速度的FastMM后,经试用,效果确实不错,于是我便在找一下FastMM在其它方面的应用。地址:http://sourceforge.net/projects/fastmm发现这个FastMM同样可以使Delphi以及用Delphi开发的程序变得更快(包括C++ Build 6)使用方法:解开FastMM427.zip,找到里面的FastMm427Replacement BorlndMM DLLPrecompiledfor Delphi IDEPerformance目录下的borlndMM.dll文件,把它复制到Delphi安装目录的bin中,把原文件覆盖即可。在应用程序中的使用,作者是这样说的:Using FastMM is very simple. All you have to do is add FastMM.pas as the very first unit in your project's .dpr file. Note that if you application uses .DLL files and you will be sharing memory (i.e. passing long strings or dynamic arrays between the DLL and main application), that you have to use FastMM in the DLL as well. If FastMM is not the first file in the "uses" section of the .dpr file, you will get an "invalid pointer operation" during program startup (meaning the default MM has already been used to allocate some memory). 意思是您只需要把FastMM4.pas加入到你的项目中,但要保证dpr文件uses后面第一个文件就是FastMM4.pas即可,经过本人实验,实际使用中还要加FastMM4Messages.pas或者设置一个搜索路径(设路径比较麻烦,还是加进来吧)。然后编译你的程序就可以了。如果你的dll用了共享内存,那么就用FastMM427Replacement BorlndMM DLLPrecompiledfor ApplicationsPerformance中的BorlndMM.dll和你的DLL文件一起分发即可。因为没看到盒子上有这方面的东西,因此就上传一个了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值