1

当它在 GET 之后等待服务器的响应并且线程被终止时,我有一些与 TidHTTP 相关的内存泄漏。

例子 :

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

谢谢 :)

4

2 回答 2

8

你应该打电话

aThread.WaitFor;

在销毁线程之前。这确保线程正确终止。销毁线程而不终止它可能会导致执行方法中的访问冲突,从而导致 FastMM 显示内存泄漏。

编辑考虑到问题可能是您的执行方法中的阻塞调用,您可能希望将 TIdHttp.ReadTimeOut 设置为合理的时间并定期检查线程终止。

于 2009-10-05T09:16:48.110 回答
-1

Indy 还会产生两到三个预期的内存泄漏,例如整数和临界区。但他们可能会也可能不会按预期注册。所以我不知道这些是不是你看到的。如果您将代码运行 5 次,您会看到比现在更多的泄漏吗?

至于 Smasher 建议的 WaitFor,在调用 Free 之前调用。这不应该是必需的,也不是问题的原因,因为如果您检查 TThread 的析构函数,您会看到已经完成了。

为什么你的泄漏报告中出现访问冲突,我真的不知道。但是,您从线程外部调用 Disconnect,而 Indy 组件正在您的线程中使用。不要那样做,使用来自不同线程的相同的非线程安全组件是自找麻烦。这可能会导致您的访问冲突泄漏。让线程本身执行对 Indy 组件的所有调用。

按照 Smasher 的建议减少 ReadTimeOut 是一个好主意,但要确保您的应用程序不会阻塞太久。

于 2009-10-05T11:23:18.473 回答