FLD*_*phi 6 delphi memory-leaks delphi-10-seattle
我已经创建了一个控制台应用程序并设置了ReportMemoryLeaksOnShutdown:= True.
我已经创建了一个TStringList但没有释放它.
程序完成执行后,我会看到内存泄漏一小段时间,然后控制台关闭.
我试过添加一个ReadLn; 到最后,但是当我这样做时它只显示一个空白的控制台窗口,这是有道理的.
我需要找到一种在内存泄漏报告之后暂停执行的方法,但是在完成程序关闭之前.
我正在使用Delphi 10 Seattle.
program Project1;
{$APPTYPE CONSOLE}
uses
System.Classes,
System.SysUtils;
var
s : TStringList;
begin
try
ReportMemoryLeaksOnShutdown := True;
s := TStringList.Create;
//ReadLn doesn't work here, which makes sense.
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
//I need to be able to pause the program somewhere after the end statement here.
end.
Run Code Online (Sandbox Code Playgroud)
这是最近的Delphi版本中的一个错误.我刚刚在最近的免费Delphi 10.1 Starter中检查了它,它的行为和你描述的一样 - 但由于它没有提供RTL源,我无法检查确切的原因.
在Delphi XE2中,它按预期运行:创建任务模式对话框并等待您做出反应,就像Sertak所描述的那样.
在Delphi 10.1中,确实会向控制台窗口报告泄漏,但程序不会停止等待用户注意.这是一个糟糕的解决方案,因为这个原因以及在脚本中可能使用控制台程序(CMD或PS脚本不会"理解"此消息,并且可能会将其与合法输出混淆并且无法执行其他阶段程序.
我认为你必须在Delphi 10.0上打开回归型错误报告 - 但我认为他们不会在10.2版本之前修复它.
我还将您的应用程序从Delphi-forked内存管理器切换到原始应用程序,然后还原了错误的行为:程序显示消息框并等待直到我退出进入IDE之前将其解除.
目前我建议你使用上面提到的原始内存管理器而不是Delphi的fork.
program Project1;
{$APPTYPE CONSOLE}
uses
FastMM4,
System.Classes,
System.SysUtils;
...
Run Code Online (Sandbox Code Playgroud)
原始内存管理器驻留在http://github.com/pleriche/FastMM4 您可以在Delphi中使用Git客户端或独立的Git客户端来保持自己的更新,或者您可以下载代码一次并停止更新,由您决定.
其代码的相关引用是:
{$ifdef LogErrorsToFile}
{Set the message footer}
LMsgPtr := AppendStringToBuffer(LeakMessageFooter, LMsgPtr, Length(LeakMessageFooter));
{Append the message to the memory errors file}
AppendEventLog(@LLeakMessage[0], UIntPtr(LMsgPtr) - UIntPtr(@LLeakMessage[1]));
{$else}
{Set the message footer}
AppendStringToBuffer(LeakMessageFooter, LMsgPtr, Length(LeakMessageFooter));
{$endif}
{$ifdef UseOutputDebugString}
OutputDebugStringA(LLeakMessage);
{$endif}
{$ifndef NoMessageBoxes}
{Show the message}
AppendStringToModuleName(LeakMessageTitle, LMessageTitleBuffer);
ShowMessageBox(LLeakMessage, LMessageTitleBuffer);
{$endif}
end;
end;
{$endif}
end;
Run Code Online (Sandbox Code Playgroud)
和
{Shows a message box if the program is not showing one already.}
procedure ShowMessageBox(AText, ACaption: PAnsiChar);
begin
if (not ShowingMessageBox) and (not SuppressMessageBoxes) then
begin
ShowingMessageBox := True;
MessageBoxA(0, AText, ACaption,
MB_OK or MB_ICONERROR or MB_TASKMODAL or MB_DEFAULT_DESKTOP_ONLY);
ShowingMessageBox := False;
end;
end;
Run Code Online (Sandbox Code Playgroud)
这段代码依赖于在桌面Windows上运行,因此也许Embarcadero试图"修复"它以使其跨平台.然而,他们这样做的方式在Windows控制台上打破了它....
还要考虑使用添加其他形式的日志记录 - 进入文件和/或Windows调试字符串.它们不像模态窗口那样引人注目,但至少可以帮助您保存信息,如果你知道在哪里寻找它.
最简单的方法是在先前打开的命令窗口中运行应用程序.
如果您在IDE中运行时仍坚持查看内存泄漏报告,请执行以下操作:
end;过程上放置一个断点.另外,正如Sertac Akyuz评论的那样end.,在system单位上设置了一个断点.
您还可以将内存泄漏报告重定向到文件.从中下载完整版的FastMM
https://sourceforge.net/projects/fastmm/
或者更好,感谢Arioch'The,从这里:
https://github.com/pleriche/FastMM4
并设置所需的选项 FastMM4Options.inc
var
SaveExitProcessProc: procedure;
s: TStringList;
procedure MyExitProcessProc;
begin
ExitProcessProc := SaveExitProcessProc;
readln;
end;
begin
SaveExitProcessProc := ExitProcessProc;
ExitProcessProc := MyExitProcessProc;
ReportMemoryLeaksOnShutdown := True;
s := TStringList.Create;
end.
Run Code Online (Sandbox Code Playgroud)
这肯定是一个 hack,不要在生产中使用:)
ReportMemoryLeaksOnShutdown:= True;
IsConsole:= False;
TStringList.Create;
Run Code Online (Sandbox Code Playgroud)
但是,它会导致泄漏消息(以及一些其他消息)显示在消息框中(可以通过按 Ctrl+C 复制所有文本)。
(使用 Delphi 10.2 进行测试,请报告我们不喜欢的任何副作用)
| 归档时间: |
|
| 查看次数: |
4362 次 |
| 最近记录: |