delphi - 是什么导致了 Delphi 中的内存泄漏?

标签 delphi delphi-2009

我无法弄清楚 EurekaLog 为我的程序报告的内存泄漏。我正在使用 Delphi 2009。这是:

Memory Leak: Type=Data; Total size=26; Count=1;
The stack is:
System.pas  _UStrSetLength  17477
System.pas  _UStrCat           17572
Process.pas  InputGedcomFile  1145

这就是堆栈中的全部内容。 EurekaLog 将我指向未释放的内存最初分配的位置。根据它,我程序中的行是 InputGedcomFile 的第 1145 行。那一行是:

CurStruct0Key := 'HEAD' + Level0Key;

其中 CurStruct0Key 和 Level0Key 在过程中被简单地定义为局部变量,在进入和离开过程时应该由 Delphi 内存管理器动态处理:

var CurStruct0Key, Level0Key: string;

现在我查看系统单元中的 _UStrCat 过程。第 17572 行是:

CALL    _UStrSetLength  // Set length of Dest

然后我转到系统单元中的 _UStrSetLength 过程,相关行是:

@@isUnicode:
        CMP     [EAX-skew].StrRec.refCnt,1 // !!! MT safety
        JNE     @@copyString  // not unique, so copy

        SUB     EAX,rOff      // Offset EAX "S" to start of memory block
        ADD     EDX,EDX       // Double length to get size
        JO      @@overflow
        ADD     EDX,rOff+2    // Add string rec size
        JO      @@overflow
        PUSH    EAX           // Put S on stack
        MOV     EAX,ESP       // to pass by reference
        CALL    _ReallocMem
        POP     EAX
        ADD     EAX,rOff      // Readjust
        MOV     [EBX],EAX     // Store
        MOV     [EAX-skew].StrRec.length,ESI
        MOV     WORD PTR [EAX+ESI*2],0 // Null terminate
        TEST    EDI,EDI       // Was a temp created?
        JZ      @@exit
        PUSH    EDI
        MOV     EAX,ESP
        CALL    _LStrClr
        POP     EDI
        JMP     @@exit

第 17477 行是“CALL _ReallocMem”行。

那么什么是内存泄漏呢?当然,将字符串常量简单地连接到本地字符串变量不应导致内存泄漏。

为什么 EurekaLog 将我指向作为 Delphi 一部分的 _UStrSetLength 例程中的 ReallocMem 行?

这是 Delphi 2009,我正在使用新的 unicode 字符串。

如有任何帮助或解释,我们将不胜感激。


找到的解决方案:

字符串被分配给新菜单项的属性。菜单项已添加到菜单中。然后新的菜单项被释放,因此我认为一切都被清理干净了。因为字符串(通过引用计数)仍在使用,因为它被复制到项目中,所以字符串没有在内存中释放,即使它在例程中作为局部变量引入也是如此。

通常这不应该是泄漏。但是,我的程序有时会使用“menu.item.delete(i)”删除各种菜单项。我没有意识到的是删除不会释放项目本身的内存。因此,引用计数的字符串没有被释放,从而导致泄漏。

解决方案是将我的“menu.item.delete(i)”语句更改为:“menu.item[i].free”。

最佳答案

它会将您指向分配相关内存的那一行。你是对的,处理字符串应该由编译器处理。您可能遇到了以下两个问题之一。

  1. 这不是您泄露的唯一内容。该字符串属于一个永远不会被清理的对象。例如,CurStruct0Key 可能会传递给构造函数,并在构造函数中将其分配给对象。或者
  2. 您正在对字符串做一些棘手的事情,例如将其转换为指针并四处传递。不要这样做!它可以阻止引用计数!

检查是否是这些原因导致了您的问题。

关于delphi - 是什么导致了 Delphi 中的内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1977355/

相关文章:

delphi - 不同类中的相同属性和过程。如何访问它们?

delphi - 创建一个函数以将十六进制值反转为字符串

delphi - 如何比较包含对象函数/过程的 TFunc/TProc?

delphi - 从主线程更改线程的变量值是否安全?

c++ - 用于在 C++ 或 Delphi 中开发 XMPP 服务器的库?

delphi - d2007设置对外部程序的依赖

delphi - Delphi 中 DLL 的隐式链接与显式链接

delphi - Delphi 2009升级问题

delphi - 如何在我的自定义组件中包含位图(如果可能)?

Delphi Pascal - 使用 SetFilePointerEx 和 GetFileSizeEx,在读取文件时获取物理媒体的确切大小