17

ベスト プラクティスは、IDisposable を実装するオブジェクト、特にファイル ハンドル、ソケット、GDI ハンドルなどの有限リソースをラップするオブジェクトで Dispose を呼び出すことです。

しかし、Font を持つオブジェクトがあり、オブジェクトのいくつかのレイヤーを介して IDisposable を配管し、多くの使用法を確認して、Font が常に破棄されるようにする必要があります。そして、それが複雑さの価値があるかどうか疑問に思っています。

GDI リソースはシステム グローバルであるため、Font が HFONT をラップした場合は問題ありません。ただし、Font は GDI ハンドルをラップしません。それは完全に独立したシステムであるGDI +であり、私が理解している限り、GDIのようにシステムグローバルではなく、プロセスローカルです。また、Image とは異なり、Font はファイルシステム リソースを保持することはありません (とにかく、私は知っています)。

だから私の質問は次のとおりです。フォントにガベージコレクションをさせることの実際のコストはいくらですか?

ファイナライザーに小さなヒットを与えることはわかっていますが、「リークされた」フォントの数が少ない場合 (半ダースなど)、そのヒットは正直なところ目立ちません。ファイナライザーを除けば、これは中規模の配列を割り当てて GC にクリーンアップさせるのと大差ないように見えます。これは単なるメモリです。

Font を GCed にする際に、私が気付いていないコストはありますか?

4

6 に答える 6

5

問題は、ガベージ コレクションがメモリ不足の場合にのみ発生することです。多くの場合、アンマネージ ハンドルはメモリよりも制限されているため、GC が発生する前にハンドルが不足し、エラーが発生する可能性があります。

しかし、1 回か 2 回のFont場合は、それほど害はありません。

より大きな問題は、一部のオブジェクトが共有されており、時期尚早に破棄すべきではない (またはできない) ことです...

于 2009-04-15T15:57:05.173 に答える
5

簡単な答え: 数が少ない場合は、いいえ。多い場合は、はい。アプリケーションがすでにガベージ コレクターに負荷をかけている場合は、そうです。perfmon を使用して、周囲に存在するオブジェクトの数と、より高い世代に昇格する数を表示してから決定します。

于 2009-04-15T15:58:00.833 に答える
5

使い終わったら捨てないのはなぜ?街路清掃員がいるからといって、街路にポイ捨てをすればいいというわけではありません。ただし、指定された例では、オブジェクトの存続期間中にフォントが必要な場合は、そのオブジェクトの dispose でフォントを破棄します。私のコードを単純化することもたくさんありますが、それはそれらの変更を正当化するものではありません - たとえそれが苦痛であっても、あなたがしなければならないことがあります.

自分の身の回りを片付けるのは常に良い考えです。不要になったものは、処分してください。こうすることで、厄介な競合状態、メモリ不足の例外、描画の不具合、プロセッサを集中的に使用する時間のかかるガベージ コレクションを回避できます。

正当な理由 (オブジェクトを所有していないなど) がない限り、使い捨てオブジェクトが不要になった場合は、破棄することをお勧めします。問題の根本原因を追跡することは、事前に防御的にコーディングすることよりも困難です。

フォントに関して、MSDN は次のように述べています。

フォントへの最後の参照を解放する前に、必ず Dispose を呼び出してください。そうしないと、使用しているリソースは、ガベージ コレクターが Font オブジェクトの Finalize メソッドを呼び出すまで解放されません。

リソースが何であるかは述べていませんが、これを行う必要があることを明示的に述べているという事実は、暗黙的に Dispose を呼び出すことの重要性を高めます。

于 2009-04-15T16:52:58.843 に答える
3

本当に何かを処分することはどれほど重要ですか? この種の質問をし始めると、コードに設計上の問題があるように思えます。不要になったものは常に処分する必要があります。これを責任あるプログラミングと呼びます。

問題の可能な解決策:

  • のようなオブジェクトを渡さないでくださいFontsフォントを使用するロジックを 1 か所(1 つのクラス) に実装し、Font をそのクラスのフィールドとして追加し、そのクラスに実装IDisposableします。

  • Font キャッシュ クラスを実装します。コード全体で演算子を使用して新しいFontオブジェクトを作成する代わりに、このクラスを使用して目的の. クラスは、可能であれば、既存のフォントを再利用するロジックを持つことができます。または、最後の 10 個のフォントをメモリに保持し、残りを破棄します。アプリのライフサイクルで 1 回呼び出されるキャッシュ用に実装します。newFontIDisposable

于 2009-04-16T18:24:23.730 に答える
1

特にクリーンアップが必要なため、ファイナライザーはクラスに組み込まれています。クリーンアップするオブジェクトの量が多いか少ないかに関係なく、それらをクリーンアップすることをお勧めします。

GC は、独自の疑似精神を持つように構築されました。オブジェクトを適切に破棄することで、GC が本来の目的を果たすことができるようになります。

ただし、大量のフォント オブジェクトを作成し、それらすべてを破棄する場合は、適切な世代 (おそらく世代 0) で GC を頻繁に呼び出して、種類に応じて自分で GC クリーンアップを開始することをお勧めします。多数のインスタンスを作成している他のオブジェクトの。あなたの目標は、あなたが長い間使用していないことを知っているオブジェクトを古い世代に昇格させないようにすることです。これにより、GC の仕事が効率的かつ平均的なものになります。

最善の判断を下すだけで大丈夫です。ただし、実際には、通常の慣行として、ファイナライザーを使用してオブジェクトを破棄してください。

于 2009-04-15T17:23:08.663 に答える
-2

.NET ランタイムを使用する他のアプリを少なくとも 1 つ実行しています。OutOfMemoryExceptions が発生し続けます。十分なリソースを取得できない場合に他のアプリが例外をスローしないように、アプリケーションを動作させるとよいでしょう。

于 2013-02-20T00:11:46.243 に答える