我有一些与TIDHTTP相关的内存泄漏,当它在GET之后等待服务器的响应并且线程被终止时。
示例:
aThread = class(TThread)
private
FidHTTP :TidHTTP;
FCommand :String;
public
procedure Execute(); override;
constructor Create(aCommand :String); override;
procedure Disconnect;
end;
procedure aThread.Execute();
var response :String;
begin
response := FidHTTP.Get(FCommand);
end;
procedure aThread.Disconnect;
begin
if ((FidHTTP <> nil) and (FidHTTP.Connected)) then FidHTTP.IOHandler.CloseGracefully;
end;
constructor aThread.Create(aCommand :String); override;
begin
FCommand := aCommand;
inherited Create;
end;
当应用程序关闭时,我用这个停止线程:
aThread.Disconnect;
aThread.Terminate;
aThread.Free;
我该怎么做来解决记忆泄漏?
FastMM4 Log :
13 - 20 bytes: TIdThreadSafeInteger x 1
21 - 36 bytes: EAccessViolation x 1, TIdCriticalSection x 2
181 - 212 bytes: UnicodeString x 1
谢谢:)
答案 0 :(得分:8)
你应该致电
aThread.WaitFor;
在销毁线程之前。这可以确保线程正确终止。在不终止线程的情况下销毁线程可能会导致执行方法中的访问冲突,从而导致FastMM显示内存泄漏。
编辑考虑到问题可能是执行方法中的阻塞调用,您可能希望将TIdHttp.ReadTimeOut设置为合理的时间并定期检查线程终止。
答案 1 :(得分:-1)
Indy还会产生两到三个预期的内存泄漏,如整数和临界区。但它们可能会或可能没有按预期注册。所以我不知道这些是你看到的那些。如果你运行你的代码5次,你会看到比现在看到更多的泄漏吗?
至于Smasher建议的WaitFor,在调用Free之前调用。这不应该是需要的,也不是你的问题的原因,因为如果你检查TThread的析构函数,你会看到已经完成了。
为什么您在泄漏报告中收到访问冲突,我真的不知道。但是,您在线程外部调用Disconnect,而Indy组件正在您的线程中使用。不要这样做,使用来自不同线程的相同非线程安全组件会遇到麻烦。这可能会导致您的访问冲突泄露。让线程本身对Indy组件进行所有调用。
按照Smasher的建议减少ReadTimeOut是个好主意,但要确保你的应用程序不会阻塞太久。