FastMM 定位内存泄露的代码位置

开源的FastMM,使用很简单,在工程的第一行引用FastMM4即可(注意,一定要在第一个Uses的位置),可以在调试程序时提示内存泄露情况,还可以生成报告。

在Delphi2007以后版本中,使用更加简单,只需要在工程开始的位置加上语句:

ReportMemoryLeaksOnShutdown := True;就可以了,并且在运行时不会出现提示。如果想要生成文件报告,还需要FastMM4,Delphi中没有别的设置可以生成文件报告。

可以修改FastMM4Options.inc中的参数开关来修改内存管理的相关设置。

使用说明如下:

1.打开FastMM4的调试功能

首先在自己的project里把FastMM4放在最前面,例如:

FastMM4,

Main   in   ‘Main.pas’   {MainForm},

再修改FastMM4Options.inc,打开全调试模式。例:

{$define   FullDebugMode}

也可以在project中定义编译常量:FullDebugMode。

同时把FastMM_FullDebugMode.dll拷贝到编译后生成的可执行程序所在目录。

再要打开内存泄漏报告:EnableMemoryLeakReporting。一般情况下是缺省打开的。  这样就打开了全调试模式,如果发生内存泄漏将会生成报告文件,如果在IDE运行的时候还会弹出一个对话框显示。报告文件类似:XXX_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窗口正中就是内存映像,而且源码也相应地标注好了,左边列的地址就是内存报告中的Call   Stack中的地址,翻页找到所对应的代码就知道哪里分配内存了。

2.检查释放内存的地方是否被调用

可以用日志或断点来调试,如果压根就没有释放内存那就补上代码,如果有却没有执行则检查一下执行条件是否正确,如果断点没起作用很可能是因为代码永远不会被执行(死代码)。这要靠经验和调试,基本上借助IDE和内存报告就可以很好地防止内存泄漏。同时要加强测试用例,争取在测试用例中能遍历到所有的代码和大部分关键功能,这样内存泄漏报告就会更准确一点。

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

另外:

1).内存管理不是GC自动回收内存,而是检查是否有泄漏。   
  2).windows系统的内存泄漏是无法检查的,仅限于应用程序内部,不过检查出系统泄漏也没办法,只能等更新了。       
  3).检查泄漏后要自己去检查代码补齐内存释放,报告并不能做这事

FastMM 定位内存泄露的代码位置的更多相关文章

  1. 利用linux的mtrace命令定位内存泄露(Memory Leak)

    一谈到内存泄露, 多数程序猿都闻之色变. 没错, 内存泄露非常easy引入. 但非常难定位.  以你我的手机为例(如果不常常关机). 如果每天泄露一些内存, 那么開始的一个星期, 你会发现手机好好的. ...

  2. 强大的windbg定位内存泄露,两句命令搞定!

    1.简单配置在windbg程序目录下有个gflags.exe,运行后设置: 运行CMD.EXE,输入"D:\Debugging Tools for Windows (x86)\gflags. ...

  3. Delphi xe 下快捷使用 FastMM 的内存泄露检测功能

    Delphi xe 集成了FastMM,调试程序是的时候可以方便地检查内存泄露了.  使用方法:在project中,添加一行: ReportMemoryLeaksOnShutdown := Debug ...

  4. Android NDK定位.so文件crash代码位置

    参考:http://blog.csdn.net/xyang81/article/details/42319789 问题:      QRD8926_110202平台的Browser必现报错.(去年的项 ...

  5. xcode8 使用Instruments检测定位并解决iOS内存泄露

    https://www.jianshu.com/p/9bc7e65fc247 2017.07.27 17:24* 字数 628 阅读 1319评论 6喜欢 21 简介: 虽然苹果出了ARC(自动内存管 ...

  6. 使用Xcode8的Instruments检测解决iOS内存泄露(leak)

    在苹果没有出ARC(自动内存管理机制)时,我们几乎有一半的开发时间都耗费在这么管理内存上.后来苹果很人性的出了ARC,虽然在很大程度上,帮助我们开发者节省了精力和时间.但是我们在开发过程中,由于种种原 ...

  7. leaks工具查找内存泄露

    作为一名iOS开发攻城狮,在苹果没有出ARC(自动内存管理机制)时,我们几乎有一半的开发时间都耗费在这么管理内存上.后来苹果很人性的出了ARC,虽然在很大程度上,帮助我们开发者节省了精力和时间.但是我 ...

  8. 使用Xcode7的Instruments检测解决iOS内存泄露

    文/笨笨的糯糯(简书作者)原文链接:http://www.jianshu.com/p/0837331875f0著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 作为一名iOS开发攻城狮, ...

  9. 在Blade中结合gperftools检查内存泄露

    Blade是我们开发的大规模C++项目构建工具. gperftools是google开发的性能工具,由高效内存分配器,CPU性能分析器,堆分析器,堆检查器等工具组成. 和其他构建工具不同,结合gtes ...

随机推荐

  1. Linux系统下设置Tomcat自启动

    需要将tomcat加入自启动队列中,则需要进行如下的操作: 以root用户登录系统: cd /etc/rc.d/init.d/ vi tomcat 文件内容参考如下: #!/bin/sh # # to ...

  2. js获取url方法

    //设置或获取对象指定的文件名或路径.alert(window.location.pathname); //设置或获取整个 URL 为字符串.alert(window.location.href); ...

  3. WPF样式

    <Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winf ...

  4. Delphi线程同步(临界区、互斥、信号量)

    当有多个线程的时候,经常需要去同步这些线程以访问同一个数据或资源. 例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件的字符数.当然,在整个文件调入内存之前,统计它的计数是 ...

  5. gcc参数-l传递顺序错误导致`undefined reference'的一点小结

    刚才编译一个pthread的单文件程序, 使用的命令行是: gcc -o thread1 -lpthread thread1.c 结果报错: $ gcc -o thread1 -lpthread th ...

  6. 【计算机图形学】openGL常用函数

    OpenGL常用函数   glAccum 操作累加缓冲区   glAddSwapHintRectWIN 定义一组被 SwapBuffers拷贝的三角形   glAlphaFunc允许设置alpha检测 ...

  7. 对服务器的ftp端口进行修改

    对服务器的ftp端口进行了修改,把21端口改了,比如221端口,就这样用221连接的时候,连接登录成功,但打不开目录,为何,总结如下: 1.完成一个FTP的传输过程不仅仅只需要21一个端口,而是2个端 ...

  8. lvs+keepalived 负载均衡

    LVS是一个开源的软件,可以实现LINUX平台下的简单负载均衡.LVS是Linux Virtual Server的缩写,意思是Linux虚拟服务器.目前有三种IP负 载均衡技术(VS/NAT.VS/T ...

  9. supervisor使用

    supervisor是一个C/S系统,它可以在类unix操作系统让用户来监视和控制后台服务进程的数量,一个很重要的功能就是监控服务器的主要后台进程,并在出现问题是自动重启. 根据服务器上的python ...

  10. PHP连接打印机

    <?php header("Content-type: text/html; charset=utf-8"); class Netprint{ public $host = ...