FastMM4 查内存泄露 smartbird 2011-10-8 环境: Delphi 2006、FastMM4 步骤: 1,在 Delphi 工程上右键,选择 View Source(或者选中工程,按快捷键 Ctrl + V) 2,在打开的工程源文件页签的第一个 uses 节中,添加 FastMM4 单元引用 3,在工程上右键,打开 Options 4,在弹出的对话框中,选择Directories/Conditionals 页签,点击Conditional Defines 后的省略号按钮 5,在添加3 个条件编译指令: Fu llDebu gMode LogMemory LeakDetailToFile ClearLogFileOnStartu p 6,再次执行步骤 3, 选择Linker 页签,将 Map file 选项选成 Detailed; 选择Compiler 页签,将 Use debu g DCUs 勾选 和 7,再次执行步骤3,这次选择Packages 页签,将Build w ith runtime packages 选项去掉,不勾选,即通常所说:不带包编译 8,在Form 的OnCreate 事件中,创建一个TStringList,不释放,作为测试。 9,运行程序,直接点击关闭,这样 TStringList就泄露了。 10,关闭程序后,FastMM4 弹出了内存泄露窗体,对于大型程序来说,这些还不够,因为我们不知道到底哪儿发生了泄露。 But Steve Jobs who just left us a moment ago often say: There is one more thing 11,在 exe 同级目录下,还有一个 txt 文件: 12,双击打开,能够看到泄露的内存初始分配时的堆栈: 我们能够看到Unit1.pas 文件中的,第 29 行,进行了对象创建,对比步骤 8 的截图,正是第29 行我们创建了对象。这样我们知道了,泄露的内存的分配时机,通过分析,我们在适当的时候释放泄露的对象即可。 备注说明: 1,u ses 了 FastMM4 单元(步骤 2),步骤 10 就能弹框出现 2,执行了步骤 5,就会有日志文件生成。 3,执行了步骤 6,日志文件中才会有人能够理解的堆栈信息。 4,选择不带包编译的原因是:有些项目会将 FastMM4 放入自有的公共资源包或者库中,统一管理。如果选择带包编,请确认将 FastMM4 所在的包加上步骤 5 的编译指令重新编译一下。 5,FastMM4.pas 文件中,有一个参数,一般不需要改 StackTraceDepth:生成的日志文件的堆栈深度,看注释如果要修改的话,要改成一个奇数。改了这个之后,生成的堆栈深度会更深。对于一些十分难找的内存泄露,可以尝试着改一下这个。我查了很多内存泄露,这个方法,只用了一次,查完,又改回来了。 6,步骤 6 中,勾选 Debu g DCUs 和不勾选有所区别,不是特别清楚,建议勾选,以下是现象: a)不勾选 b)勾选(文件名有区别,同时堆栈深度和 StackTraceDepth=11 一致) 7,设置完选项,请先保存然后再重编。 8,最最重要:请信任 FastMM,如果报泄露了,那一定是泄露了。因为引用 FastMM 之后,内存的分配就被 FastMM 接手了。