1

TidHTTP が 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 によって表示されるメモリ リークが発生します。

EDIT問題がexecuteメソッドの呼び出しをブロックしている可能性があるという事実を考慮すると、 TIdHttp.ReadTimeOut を適切な時間に設定し、定期的にスレッドの終了を確認することができます。

于 2009-10-05T09:16:48.110 に答える
-1

Indyは、整数やクリティカルセクションのように、2つまたは3つの予想されるメモリリークも生成します。ただし、期待どおりに登録されている場合とされていない場合があります。ですから、これらがあなたが見ているものであるかどうかはわかりません。コードを5回実行すると、現在よりも多くのリークが発生しますか?

Smasherによって提案されたWaitForについては、Freeを呼び出す前に呼び出すこと。TThreadのデストラクタをチェックすると、それがすでに行われていることが正確にわかるため、これは必要ではなく、問題の原因でもありません。

リークレポートでアクセス違反が発生する理由はわかりません。ただし、Indyコンポーネントがスレッドで使用されているときに、スレッドの外部から切断を呼び出しています。異なるスレッドから同じ非スレッドセーフコンポーネントを使用すると、問題が発生するため、これを行わないでください。これにより、アクセス違反がリークする可能性があります。スレッド自体に、Indyコンポーネントへのすべての呼び出しを実行させます。

Smasherによって提案されたようにReadTimeOutを減らすことは良い考えですが、アプリケーションが長くブロックしすぎないようにするためです。

于 2009-10-05T11:23:18.473 に答える