如何使用fastMM追踪棘手的内存泄漏?

时间:2008-11-07 11:52:02

标签: delphi memory-leaks delphi-2009 fastmm

将项目从Delphi 2007升级到Delphi 2009后,我收到了一个未知的内存泄漏,到目前为止我一直在尝试使用fastMM来跟踪它,这里是fastMM堆栈跟踪报告:

A memory block has been leaked. The size is: 20

This block was allocated by thread 0x111C, and the stack trace (return addresses) 
  at the time was:
40339E [System.pas][System][@GetMem][3412] 534873 [crtl][_malloc]
56D1C4 [canex.cpp][MidasLib][DllGetDataSnapClassObject][3918]
56D316 [canex.cpp][MidasLib][DllGetDataSnapClassObject][3961]
56D5EE [canex.cpp][MidasLib][DllGetDataSnapClassObject][4085]
562D48 [DBCommon.pas][DBCommon][TFilterExpr.PutExprNode][1583]
408E46 [System.pas][System][DynArraySetLength][20464]
56D5EE [canex.cpp][MidasLib][DllGetDataSnapClassObject][4085]
408E92 [System.pas][System][@DynArraySetLength][20486]
528C1B [Forms.pas][Forms][TCustomForm.DoCreate][3260]
171A1A [GetRawStackTrace]

The block is currently used for an object of class: Unknown

The allocation number is: 302844

有时我得到这个:

A memory block has been leaked. The size is: 20

This block was allocated by thread 0x111C, and the stack trace (return addresses) 
  at the time was:
40339E [System.pas][System][@GetMem][3412]
534873 [crtl][_malloc]
56D1C4 [canex.cpp][MidasLib][DllGetDataSnapClassObject][3918]
56D316 [canex.cpp][MidasLib][DllGetDataSnapClassObject][3961]
77DC921A [RtlAnsiStringToUnicodeString]
56D5EE [canex.cpp][MidasLib][DllGetDataSnapClassObject][4085]
7726B8F5 [GetProcAddress]
7726B907 [GetProcAddress]
589B1E [ossrv.cpp][MidasLib][DllGetDataSnapClassObject][3163]
56D5EE [canex.cpp][MidasLib][DllGetDataSnapClassObject][4085]
408E92 [System.pas][System][@DynArraySetLength][20486]

The block is currently used for an object of class: Unknown

有没有更好的方法来弄清楚导致内存泄漏的原因是什么?

6 个答案:

答案 0 :(得分:9)

此内存泄漏是由Delphi错误QC #67709

引起的

最新的Delphi 2009更新修复了这一点,难怪我无法修复它。

答案 1 :(得分:7)

只要泄漏的内存块的大小没有增长,程序的使用时间越长越长,那么这不是一个问题。如果你有一个长期存在的对象,只有在你终止应用程序时才会释放它,就像你泄露它们一样 - 所有内存都在终止时被回收(除非它们处理超出内存的资源)。

您想要关注的内存泄漏是随着时间或使用而累积的内存泄漏。如果它每次都是20个字节,那就不要冒汗了。

答案 2 :(得分:1)

我不知道D2009 VCL中是否有任何泄漏,因此假设您的代码中存在泄漏,首先我会检查以下内容:

  • 是否存在在该表单中创建的任何数组或列表(因为@DynArraySetLength)在您处置表单时未释放。
  • 是否有任何函数可以创建并返回一些应由外部调用者释放的对象,如果您有这种函数,请检查调用者是否释放该对象。
  • 如果这不显示泄漏,那么您应该检查在表单代码中创建的每个对象是否在销毁表单时被销毁。

答案 3 :(得分:1)

上一次我沿着这些线路出现了一个令人费解的漏洞,我查看了有问题的对象的原始记忆 - 并看到了显示我是什么类型数据的文本。当它说它不知道它是什么类型的对象时,可能意味着它首先不是一个对象 - 所以看看动态分配的东西,包括字符串。

答案 4 :(得分:0)

IIRC VCL有一些非常小的泄漏,你可以毫不费力地忽略。这可能就是其中之一!?希望有人澄清这一点。

答案 5 :(得分:0)

我会说你在Form OnCreate事件处理程序中发生了一些正在发展DynArray的事情。
并且DynArray最终没有发布 但是,如果没有看到代码并使用FastMM实际调试它,几乎无法猜出实际发生了什么。