4

Delphi メモリ管理に関するいくつかの質問に対する答えを見つけることができませんでした。さまざまなシナリオをテストすることはできました (FreeAndNil メソッドを壊すものを見つけるために行いました) が、時間がかかりすぎて難しいです! しかし、真剣に、皆さん (Delphi 開発者) がこれらのメモリ管理の問題をどのように処理しているかを知りたいです。

私の質問 (自由に質問してください。質問への回答も役立つと思います):

  1. FreeAndNil は COM オブジェクトに対して機能しますか? 私の考えでは、それは必要ありませんが、nil に設定するだけでよいのであれば、finally ブロックで一貫性を保ち、すべてに FreeAndNil を使用しないのはなぜですか?

  2. 静的配列をクリーンアップする適切な方法は何ですか (myArr : Array[0..5] of TObject)。私はそれを FreeAndNil できないので、nil に設定するだけで十分ですか (各オブジェクトを FreeAnNil した後にそれを行う必要がありますか?)?

みんなありがとう!

4

4 に答える 4

8

COMオブジェクトは、インターフェイスを介して参照されます。インターフェイスは、解放するために何もする必要はありません。コンパイラは、COMオブジェクトが適切なタイミングで破棄されるように、必要な参照カウントロジックを処理します。

静的配列(または動的配列)に関しては、それらを解放する必要もありません。オブジェクトが含まれている場合、オブジェクトは適切なタイミングで解放する必要がありますが、配列は解放しません。

また、オブジェクト参照以外のものにはFreeAndNilを使用しないでください。インターフェイスまたは他の変数で使用すると、メモリが破損する可能性があります。解放して後で再利用する必要があるオブジェクトを扱っている場合を除いて、絶対に使用しない(代わりにFreeを使用する)ことをお勧めします。

于 2010-03-24T19:41:36.260 に答える
2

まず、ほとんどの場合、FreeAndNil は少し過剰です。オブジェクトのフィールドをデストラクタの外側またはグローバル (醜い) 変数で解放する場合に便利です。しかし、ほとんどの場合、無料で電話をかけるだけで十分です。

ご存知のように、オブジェクト変数は実際にはオブジェクトのデータへのポインターです。Free を呼び出すと、そのバッファーは解放されますが (もちろん、デストラクタが実行された後)、Object 変数は解放されたばかりのメモリ位置を指したままです。これは「ダングリング ポインター」と呼ばれます。ポインターがぶら下がっていることは、そのコンテキストでぶら下がっていることがわかっている限り、問題ではありません。例えば:

Procedure Myproc;
var vString : TStringList;
begin
  //Here, vString is "dangling"
  vString := TStringList.Create;
  //Here, vString is valid
  try
    //Do some stuff
  finally
    vString.Free;
  end;
  //Here, vString is "dangling"...  But who care, it's about to go out of scope and we won't use it again.
end;

FreeAndNil を呼び出すことは、いつ、どのように変数を解放できるか正確にわからないグローバル変数に対してより理にかなっています。そうは言っても、常に FreeAndNil を呼び出しても問題はありません (すべてのオンスのパフォーマンスを得ようとする非常にタイトなループを除きます)。

さて、COM オブジェクトについては... Mason が述べたように、それらは参照カウントされます。したがって、そのインターフェイスへの唯一の参照を保持している場合、呼び出すMyInterface := nil;と解放されます。ただし、変数がスコープ外になると、コンパイラはクリーンアップ コードを追加してインターフェイス参照がデクリメントされるようにします。したがって、メモリ要件を最小限に抑えようとしている場合は、インターフェイスを nil に設定してください。そうでなければ、それほど問題ではありません。

配列に関しては...リスト内のすべてのアイテムでFreeを呼び出すことができます...オプションで、後でそれらをnilに設定します。

于 2010-03-24T21:28:12.630 に答える
1

COM オブジェクトは自動的に参照カウントされます。変数がスコープ外になるか、インターフェイス ポインタをフィールドとして持つオブジェクトが削除されるとすぐに、Delphi は _Release を呼び出し、オブジェクトはそれ自体を削除します。明示的に nil を設定する必要はありません。

静的配列の場合は、それらをループして、各オブジェクトを明示的に解放する必要があります。

于 2010-03-24T19:39:42.097 に答える
1

静的配列に関しては、配列の内容を作成した場合は、作成したオブジェクトを解放するだけです。myArr 自体が使用するスペースをクリーンアップするために特別なことをする必要はありません。

于 2010-03-24T19:27:11.190 に答える