首页 > 解决方案 > Delphi Memory Leak:如何找到实际导致内存泄漏的代码行的位置

问题描述

我正在调试内存泄漏。我想找到导致内存泄漏的实际代码行。我在互联网上搜索了开源工具,发现FastMMFullDebugMode我用and 设置了它LogMemoryLeakDetailToFile。我得到以下日志文​​本文件:内存块已泄漏。尺寸为:56

This block was allocated by thread 0x3840, and the stack trace (return addresses) at the time was:

424559 [FastMM4.pas][FastMM4][_ZN7Fastmm411DebugGetMemEx][9659]
4248F6 [FastMM4.pas][FastMM4][_ZN7Fastmm415DebugReallocMemEPvx][9878]
40938D [System.pas][System][_ZN6System11_ReallocMemERPvx][4819]
412C9C [System.pas][System][_ZN6System17DynArraySetLengthERPvS0_xPx][35000]
4623F1 [System.Generics.Collections.pas][System.Generics.Collections][_ZN6System8Generics11Collections11TListHelperE@InternalSetCapacity][3845]
460BD6 [System.Generics.Collections.pas][System.Generics.Collections][_ZN6System8Generics11Collections11TListHelperE@InternalGrow][3106]
460C0D [System.Generics.Collections.pas][System.Generics.Collections][_ZN6System8Generics11Collections11TListHelperE@InternalGrowCheck][3112]
45F243 [System.Generics.Collections.pas][System.Generics.Collections][_ZN6System8Generics11Collections11TListHelperE@InternalAdd8][2487]
6EF13D [System.JSON.pas][System.JSON][_ZN6System4Json11TJSONObjectE@AddDescendant][1831]
6EF64E [System.JSON.pas][System.JSON][_ZN6System4Json11TJSONObjectE@ParsePair][1979]
6EF4BB [System.JSON.pas][System.JSON][_ZN6System4Json11TJSONObjectE@Parse][1924]
The block is currently used for an object of class: Unknown

所以它只通知是否发生任何内存泄漏。我不明白如何使用这个文件并找到导致内存的实际代码行。有什么方法可以轻松找到吗?

标签: delphimemory-leaksfastmm

解决方案


要查找内存泄漏,madExcept确实是一个很好的工具。它非常易于使用,不需要对源代码进行任何修改。

在 Delphi 中安装后,您在“项目”下有一个新的“madExcept 设置...”菜单项,它提供以下屏幕:

在此处输入图像描述

在那个屏幕转储上,我已经检查了正确的选项来检测内存泄漏等。

只需编译并运行您的程序。当你退出它时,它会生成一个错误报告。例如,假设你有这个在第 28 行创建内存泄漏的源代码:

在此处输入图像描述

生成以下报告:

在此处输入图像描述

该报告显示一个内存泄漏。泄漏是一个 TObject 实例,发生在程序启动后 2.47 秒。调用堆栈显示 GetMem 在没有相应的 FreeMem 的情况下被调用。如果按照调用堆栈,可以看到第 28 行的 TForm10.Button1Click 是我编写的代码中的罪魁祸首。

madExcept 报告的不仅仅是内存泄漏:它还报告资源泄漏、缓冲区溢出或下溢以及冻结的主线程。


推荐阅读