【发布时间】:2009-12-29 22:32:40
【问题描述】:
我只是无法弄清楚 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;
所以现在我看一下系统单元中的 _USrCat 过程。第 17572 行是:
CALL _UStrSetLength // Set length of Dest
然后我进入System Unit中的_USrSetLength过程,相关行是:
@@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”。
【问题讨论】:
-
这是报告中唯一的泄漏吗?
-
不,还有很多其他的。但是他们中的大多数都像这个,这似乎表明 _ReallocMem 是一个问题。我以这个特定的例子为例,因为我看不出我的代码是如何导致这种情况的。
-
有一个很好的方法可以追踪内存泄漏,这与您正在做的事情相反。不要看你泄露最多的变量类型,看看你泄露最少的类型,因为它很可能会拥有一堆其他的东西你在泄漏。先修复这个泄漏,然后看看你的内存泄漏列表变小了多少。
-
似乎有一种“艺术”来堵漏。我必须先从静态艺术开始,然后再转向肖像。
-
不。编程涉及很多艺术,但泄漏跟踪是一门精确的科学。基本规则是每块内存都应该有一个所有者(或者是一个数据结构,比如一个对象,或者一个引用计数系统,或者一个代码块),并且所有者负责清理它的所有变量。不再需要时拥有。从这两个规则中,您可以通过一些分析得出从所有权树开始尽可能高的原则。 :)
标签: delphi delphi-2009