2009-03-13 14 views
3

オブジェクトを廃棄して所有するすべてのオブジェクトを解放できるようにする必要がありますが、IDisposableは実装されていないため、使用ブロックで使用できません。ガベージコレクタで収集するにはどうすればよいですか?1つのオブジェクトのガベージコレクションC#

答えて

9

GC.Collect()で強制的にコレクションを作成できます。完全なコレクションには時間がかかる可能性があるので、これを使用して非常に注意してください。ベストプラクティスは、収集するベストタイムがいつGCによって決定されるかだけです。

オブジェクトに管理されていないリソースが含まれていますが、IDisposableは実装されていませんか?もしそうなら、それはバグです。

ガベージコレクタがすぐに解放されるかどうかは関係ありませんが、ガベージコレクタは正しいことを行う必要があります。

+0

私は彼の質問は管理されたリソースを含んでいるためだと思うが、それは多くのリソースを使用するので、彼はオブジェクトをもう必要としないときに即座にリリースしたい。 – DevinB

+0

これが当てはまる場合は、GCで処理します。リソースが十分に大きく、メモリ圧迫が十分であれば、次の世代のGCで処理されます。 – Michael

+0

実際にはソケットを保持していて、ソケットをできるだけ早くリリースしたいのですが、自分でソケットを閉じるためのアクセス権がありません。 – Malfist

0

オブジェクトが有効範囲外になり、外部参照がない場合、オブジェクトはかなり高速に収集されます(次のコレクションの可能性があります)。

+0

必ずしもそうではありません。例えば。すでに2世代に移動している場合はしばらく時間がかかり、保留中のファイナライザがある場合は2回の収集が必要です。 –

2

メモリ以外のものを所有している場合は、IDisposableを使用するようにオブジェクトを修正する必要があります。あなたが管理しているオブジェクトでない場合、これはベンダーが実際に.Netをどれくらいよく理解しているかのコアになるため、これを別のベンダーを選択する価値のあるものです。

自分のメモリだけであれば、多くの場合でも、オブジェクトが範囲外になることを確認するだけです。 Do notGC.Collect() —を呼び出すと、尋ねなければならないことはありません。

+0

オブジェクトはライブラリから来ており、私はそれを制御できません。それはソケットを所有しているので、ソケットを閉じて再作成する必要がありますが、ソケットを保持している間はできません。ソケットにアクセスすることはできません。 – Malfist

+0

解決策#1:あなたのクイックフィックスです:call GC.Collect();ソリューション#2は、長期的な(そして正しい)修正です:ライブラリを捨て新しいものを入手してください。 –

+1

#2は必ずしもオプションではありません:) – alchemical

2

1つのオブジェクトに対してガベージコレクションを実行することはできません。 GC.Collect()を呼び出してガベージコレクションをリクエストできますが、これはクリーンアップ対象のすべてのオブジェクトに影響します。また、後のコレクションのパフォーマンスに悪影響を与える可能性があるため、これは非常に推奨されません。

また、オブジェクトのDisposeを呼び出すと、オブジェクトのメモリがクリーンアップされません。オブジェクトは、アンマネージリソースへの参照を削除することのみを許可します。たとえば、StreamWriterでDisposeを呼び出すと、ストリームが閉じられ、Windowsファイルハンドルが解放されます。管理されたヒープ上のオブジェクトのメモリは、後続のガベージコレクションまで再利用されません。

Chris Sellsも.NET Rocksでこれについて説明しました。私はそれが彼の最初の出現の間にあったと思うが、件名は後のインタビューで再訪されたかもしれない。

フランチェスコBalenaによるこの記事でも良い参照です:

いつ、どのように処分を使用し、中に完成させるために.NETでC# http://www.devx.com/dotnet/Article/33167/0/page/1

0

ガベージコレクションが非決定論的ですそれはあなたが本当にそれが起こるときを制御することができないことを意味します。あなたは示唆することができますが、それはそれが聞くことを意味しません。

オブジェクトについてもう少し詳しく説明し、その理由を教えてください。私たちはそれに基づいていくつかの提案をすることができます。コードは常に役立ちます。オブジェクトによっては、Closeメソッドなどがあります。たぶん、その使用法はそれを呼び出すことです。メソッドのClose型またはDispose型がない場合、実際には解放される必要があるリソースが含まれている場合はおそらくメモリリークが発生するため、おそらくそのオブジェクトに依存したくないでしょう。

-2

用心:多くの場合、のF RA GMエンタのションを、GC.Collect()または一部IDisposalLOHは、オブジェクトのためである(特に大規模なオブジェクトに対して、非常に有用ではありません次に、メモリのうちにつながる〜80キロバイト+全く圧縮を実行せず、高レベルの多くの一般的なユースケースのフラグメンテーションのを受ける)(OOM)は、潜在的に何百というのMBを無料で発行します。上の時間の行進として、物事がいるかもしれないLOHのため、このサイズ(80何かキロバイト)は、オブジェクトを追いやられていないが、並列性の高い度による単純により、より少ない時間でより多くのオブジェクトにこの問題をexasperates(そしておそらくサイズが異なる)、大きなを取得しますインスタンス化/解放。

アレイのランタイムから通常、この問題の容疑者(それはまた、多くの場合、ハード起因する非特異的な例外に識別するためだと表明、だろう「ラージオブジェクトヒープの断片化の高い%」のようなものがありますこの問題を抱えるコードの予後は、に攻撃的な再使用戦略を実装しています。 parallel extensions beta1 samplesからSystems.Collections.Concurrent.ObjectPool

クラスは(残念ながら、おそらくいくつかの添付プロパティ/拡張メソッドのように、私が見てきたシンプルなユビキタスパターンは、ありません?)助け、それは十分に簡単ですほとんどのプロジェクトでドロップまたは再実装するには、ジェネレータFunc <>を割り当て、Get/Putヘルパーメソッドを使用して、以前のオブジェクトを再利用し、通常のガベージコレクションを使用します。通常、配列のに焦点を当てて、個々の配列要素ではなく、で十分です。

.NET 4がすべての.ToArray()メソッドを更新して、.ToArray(T target)をインクルードするといいでしょう。

問題のこのクラスを分析するために(SOS mscoreei CLRv4用.loadby)SOS/windbgのを使用してのこつを助けることができるの取得。それについて考えると、現在のガベージ・コレクション・システムは(同じ物理メモリーを使用して)ガベージ・リサイクルによく似ていますが、ObjectPoolはガベージ・リユースに似ています。もし誰かが3つのRを覚えているなら、あなたのメモリ使用を減らすことは、パフォーマンスのためにも良い考えです;)

関連する問題