5

何年も前に、私は可能な限り、リソースが割り当てられた方法とは逆の順序でリソースを解放するように忠告されました。あれは:

block1 = malloc( ... );
block2 = malloc( ... );

... do stuff ...

free( block2 );
free( block1 );

640KのMS-DOSマシンでは、ヒープの断片化を最小限に抑えることができると思います。C#/。NETアプリケーションでこれを行うことには実際的な利点がありますか、それともこれはその関連性を超えた習慣ですか?

4

5 に答える 5

5

リソースが適切に作成されている場合、これは(それほど)重要ではありません。

ただし、作成が不十分なライブラリの多くは、適切なチェックを行いません。通常、リソースを割り当ての逆に破棄するということは、他のリソースに依存するリソースを最初に破棄することを意味します。これにより、ライブラリの記述が不十分な場合に問題が発生するのを防ぐことができます。(リソースを破棄することは決してありません。この場合、最初のリソースの存在に応じたリソースを使用します。)

また、他のオブジェクトに必要なリソースを誤って早めに破棄することはないので、これも良い習慣です。

次に例を示します。データベース操作を見てください。コマンド(接続を使用する)を閉じる/破棄する前に、接続を閉じたり破棄したりしないでください。

于 2009-11-09T19:37:24.667 に答える
4

気にしないでください。GarbageCollectorは、ヒープ上のオブジェクトを最適化して移動する権利を留保しているため、状況がどのような順序であるかはわかりません。

さらに、AとBを破棄し、AがBを参照する場合、Disposeメソッドは例外がスローされることなく複数回呼び出すことができるため、Aを破棄するときにAがBを破棄するかどうかは問題ではありません。

于 2009-11-09T19:36:41.993 に答える
1

オブジェクトのデストラクタが呼び出される時間を参照している場合、それはガベージコレクターであり、プログラミングはそれにほとんど影響を与えない可能性があり、言語定義によれば、それは明示的に非決定的です。

IDisposable.Dispose()の呼び出しを参照している場合、それはIDisposableインターフェースを実装するオブジェクトの動作に依存します。

一般に、呼び出し元のコードにとって重要である場合を除いて、ほとんどのFrameworkオブジェクトでは順序は重要ではありません。ただし、オブジェクトAがオブジェクトBへの依存関係を維持し、オブジェクトBが破棄される場合、オブジェクトAで特定のことを行わないことが非常に重要になる可能性があります。

ほとんどの場合、Dispose()は直接呼び出されませんが、usingまたはforeachステートメントの一部として暗黙的に呼び出されます。この場合、ステートメントの埋め込みに従って、逆順のパターンが自然に出現します。

using(Foo foo = new Foo())
using(FooDoodler fooDoodler = new FooDoodler(foo))
{
  // do stuff
  // ...
  // fooDoodler automatically gets disposed before foo at the end of the using statement.
}
于 2009-11-09T19:42:16.693 に答える
0

「ランタイムは、Finalizeメソッドが呼び出される順序を保証しません。たとえば、内部オブジェクトへのポインターを含むオブジェクトがあるとします。ガベージコレクターは、両方のオブジェクトがガベージであることを検出しました。さらに、内部オブジェクトのFinalizeメソッドが最初に呼び出されるとします。これで、外部オブジェクトのFinalizeメソッドは内部オブジェクトにアクセスしてメソッドを呼び出すことができますが、内部オブジェクトはファイナライズされており、結果は予測できない可能性があります。このため、 Finalizeメソッドが内部のメンバーオブジェクトにアクセスしないことを強くお勧めします。」

http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

したがって、LIFOのdisposeセマンティクスについては、好きなだけ心配することができますが、リークした場合、Dispose()はCLRが空想する順序で呼び出されます。

(これは多かれ少なかれ上記のウィルが言ったことです)

于 2010-02-08T00:47:34.390 に答える
0

ネストされた「usings」は、「outlived」が実際にはオンになっておらず、めったにオンになっていないことを示しています(40年の証拠の後で決して言わないでください)。これには、たとえばCMOSで実行されるスタックベースのVMが含まれます。

[MSDN.comとDuffiusがそれを消滅させようと試みたにもかかわらず、ヒープとスタックの違いをすべて管理できることはご存知でしょう。なんて賢いアイデアだろう。宇宙で]

于 2009-11-09T19:36:56.833 に答える