我无法弄清楚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”。
答案 0 :(得分:12)
它指向您分配有问题内存的行。你是对的,处理字符串应该由编译器处理。你可能会遇到两件事之一。
检查这些是否是导致问题的原因。
答案 1 :(得分:6)
获得更好的工具,如AQTime,您的“发现内存泄漏”问题将变得更加简单。 一般情况下,我尝试查找所有类泄漏(TSomething)并忽略String类型数据,因为正如上面指出的那样,如果某个泄漏的记录或类类型引用该字符串,则不会释放该字符串。整理你的类和你的记录,字符串泄漏都将为你修复。
答案 2 :(得分:0)
我在Delphi项目中遇到了内存泄漏问题。这个程序在我的机器上工作得非常漂亮,但在网络上的机器上却很快。
procedure accTrimWorkingSet;
var
hProcess: THandle;
begin
hProcess:=OpenProcess(PROCESS_SET_QUOTA, false, GetCurrentProcessId);
try
SetProcessWorkingSetSize(hProcess, $FFFFFFFF, $FFFFFFFF);
finally CloseHandle(hProcess); end;
end;
事实证明我正在使用映射潜水。当我改为UNC路径时,程序有效。
希望这有帮助。