Ошибки с Indy в резьбовом приложении! - PullRequest
1 голос
/ 05 октября 2009

У меня утечка памяти, связанная с 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

Спасибо:)

Ответы [ 2 ]

8 голосов
/ 05 октября 2009

Вам следует позвонить

aThread.WaitFor;

перед уничтожением нити. Это гарантирует, что поток правильно завершается. Уничтожение потока без его завершения, вероятно, вызывает нарушение прав доступа в методе execute, что приводит к утечкам памяти, отображаемым FastMM.

РЕДАКТИРОВАТЬ Учитывая тот факт, что проблема может заключаться в блокирующем вызове в вашем методе execute, вы можете установить для TIdHttp.ReadTimeOut разумное время и регулярно проверять завершение потока.

0 голосов
/ 05 октября 2009

Indy также производит две или три ожидаемые утечки памяти, такие как целое число и критическая секция. Но они могли или не могли быть зарегистрированы, как ожидалось. Так что я не могу сказать, это те, кого вы видите. Если бы вы запустили свой код 5 раз, вы бы увидели больше утечек, чем сейчас?

Что касается WaitFor, предложенного Smasher, для вызова перед вызовом Free. В этом не должно быть необходимости и причины ваших проблем, потому что если вы проверите деструктор TThread, вы увидите, что именно это уже сделано.

Почему вы получаете сообщение о нарушении прав доступа в своем отчете об утечке, я действительно не знаю. Однако вы вызываете Disconnect из-за пределов вашего потока, в то время как компонент Indy используется в вашем потоке. Не делайте этого, использование одних и тех же не поточно-безопасных компонентов из разных потоков порождает проблемы. Это может привести к утечке доступа. Пусть поток сам выполняет ВСЕ вызовы компонента Indy.

Сокращение ReadTimeOut в соответствии с предложением Smasher - хорошая идея, чтобы убедиться, что ваше приложение не блокируется слишком долго.

...