2012-02-09 1 views
2

私は以下のように.NetのDisposeとFinalizeメソッドについて考えています。私が間違っていれば私を修正してください。Disposeメソッドを呼び出すと、.NETのメモリがクリアされ、圧縮されますか?

Dispose:IDisposableのinferfaceを実装し、Disposeメソッドで未使用/アンマネージコードを削除します。開発者は、すぐに削除する必要がある場合は手動で呼び出す必要があります。または、GCが呼び出されたときにリソースを処分します。

ファイナライズ:GCが呼び出されると、未使用のマネージコードが解放され、IDisposableが実装されている場合はDisposeメソッドが呼び出され、アンマネージリソース(通常)が解放されます。

問題は:Disposeメソッドを使用してリソースを処分すると、メモリはすぐに解放され、(GCのように)圧縮されますか?

答えて

2

いいえ。Disposeメソッドを直接、またはusingステートメントを使用して呼び出しても、メモリは解放されません。

IDisposableを実装すると、そのクラスに保持されている管理されていないリソースをクリーンアップすることができます。

4

あなたの質問に対する答えはいいえです:オブジェクトに割り当てられたメモリを解放することは、Disposeメソッドを呼び出すこととは関係ありません。これは、ガベージコレクタがそれに着くと、正当な経過のなかで起こります。

一般的には、Disposeは、多くの場合、オペレーティング・システムによって割り当てられ、そのようなファイルハンドル、セマフォ、DBハンドル、およびその他の項目として外部リソースの解放をスピードアップするためのものです。あなたのオブジェクトが他のIDisposableオブジェクトに保持されている場合は、そのオブジェクトを処分するために処分する必要があります。

ファイナライザはガベージコレクションの一部として呼び出され、処理中に解放されていない外部リソースを解放することを目的としています(おそらく、ユーザがDisposeに電話を忘れたためです)。ファイナライザは、既にガベージコレクション中であるため、オブジェクトが保持する可能性のある他のオブジェクトのDisposeにコールしてはいけません。

+0

オブジェクトがファイナライザを実行する必要があるとシステムが判断した場合、オブジェクトを保持している他のすべてのオブジェクトは一時的に復活し、ファイナライザが実行されるまでガベージコレクションできません。ファイナライザがオブジェクト上で実行されるとき、参照を保持する他のオブジェクトは、(1)既にファイナライザを実行しているか、 (2)ファイナライザの実行をスケジュールする。または(3)他の何人かが使用している。これらのケースのどれにも、他のオブジェクトに対してDisposeを実行する必要はありませんが、それは他のオブジェクトが「GCされている」ことを意味しません。 – supercat

+0

@supercatだから、私は "すでにガベージコレクションされている"とは言わなかった - 私は、扶養家族がガベージコレクタの "パイプライン"のどこかにあり、これらのオブジェクトに 'Dispose'を呼び出すことは悪い考えです(私は難しいことを学ぶのは残念です)。 – dasblinkenlight

+0

ガベージコレクションされたオブジェクトがもう存在しないため、ガベージコレクションとは別のファイナライズを検討します。 GCからオブジェクトへの唯一の既存の参照を隠す場合(たとえば、安全でないコードを使用してintに変換した後、オブジェクト参照に戻す)、再構成されたオブジェクト参照にアクセスしようとすると同等ですconstrastによって、ファイナライズされているオブジェクトによって保持されているオブジェクト参照は、.net GCに関する限り、依然として存在するオブジェクトを参照します。 – supercat

1

ファイナライズ:GCを呼び出すと、未使用のマネージコードが解放され、IDisposableが実装されている場合はDisposeメソッドが呼び出され、アンマネージリソース(通常)が解放されます。

ここでは多少間違っています。 「それはDisposeを呼び出します」と言うと、GC自体を参照している場合は、いいえ、「自動的に」Disposeを呼び出しません。プログラマがDisposeメソッドとFinalizerメソッドの両方でクリーンアップを行うのはあなたの仕事です。

このMSDN writeup hereは、典型的な廃棄パターンを示しています。

質問:Disposeメソッドを使用してリソースを処分すると、メモリはすぐに解放され、(GCのように)圧縮されますか?

いいえ、Disposeを呼び出すとヒープメモリが解放されません。 GCが実行され、クリーンアップが実行されるまで、ヒープメモリは解放されません。

関連する問題