2009-04-15 7 views
16

私は、IDisposableを実装するオブジェクト、特にファイルハンドル、ソケット、GDIハンドルなどの有限リソースをラップするオブジェクトに対してDisposeを呼び出すことをお勧めします。Fontを処分することの重要性は、本当ですか?

私はケースに入っています私はフォントを持つオブジェクトを持っています。オブジェクトのいくつかのレイヤーを介してIDisposableを配置して、フォントを処分するように多くの用途を見直す必要があります。そして、私はそれが複雑さの価値があるかどうか疑問に思っています。

GDIリソースがシステムグローバルであるため、FontがHFONTをラップすると1つのことになります。しかしFontはGDIハンドルをラップしません。 GDI +は完全に別のシステムであり、わかっている限り、GDIのようにシステム全体ではなくプロセスローカルです。 Imageとは違って、Fontはファイルシステムのリソース(私が知っているとにかく)を保持することはありません。

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

ファイナライザのヒット数が少ないことはわかっていますが、「漏れた」フォントの数が少ない(半ダース)と、正直には目立つことはありません。ファイナライザとは別に、これは中規模の配列を割り当てることとGCのクリーンアップをさせることと大きく異なるようには見えません。

フォントをGCedにするのに気づいていないのですか?

答えて

5

単純な答え:そのわずか数ならば、ノー。それがたくさんある場合は、はい。アプリケーションがすでにガベージコレクタに重点を置いている場合は、「はい」と表示されます。 perfmonを使って座っているオブジェクトの数を見て、その数を高次の世代に昇進させてから決定します。

4

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

しかし、1つまたは2つのインスタンスでは、あなたを過度に傷つけることはありません。

大きな問題は、オブジェクトの一部が共有されていることであるといけない(あるいはできない)早まって配置されても...

+0

"管理されていないハンドルはメモリよりも制限されることが多い" - 確かに。しかし、それは具体的にGDI +フォントハンドルに当てはまりますか?それは私の質問の一部です。 –

4

完了したらどうしてそれを処分しないのですか?私たちが路上掃除機を持っているという理由だけで、私たちは街を散策しなければならないというわけではありません。ただし、与えられた例では、オブジェクトの存続期間中にフォントが必要な場合は、そのオブジェクトのdisposeにフォントを破棄します。私のコードも単純化する多くのことがありますが、それはそれらの変更を正当化するものではありません。時には、痛みはあるものの、ときどき行うべきことがあります。

自分自身を整理するのは常に良いアイデアです。もはや何かが必要なときは、それを処分してください。そうすれば、競合状態が悪くなったり、メモリ不足で例外が発生したり、グリッチが発生したり、プロセッサが長くかかるガーベッジコレクションが回避されます。

使い捨てオブジェクトを処分するのは、正当な理由がない限り(オブジェクトを所有していないなど)、不要になったオブジェクトを処分することをお勧めします。障害の根本原因を突き止めるのは、防衛的に前向きにコーディングするよりも困難です。フォント、MSDN saysに関して

:あなたがフォントへのあなたの最後の参照を解放する前に

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

リソースが何であるかは明示されていませんが、これが明示的に指定されているということは、暗黙のうちにDisposeの呼び出しを重要視しています。

+5

なぜそれを処分しないのですか?なぜなら、彼のコードを大いに単純化するからです。 –

+2

コントロールのFontプロパティ(またはPictureプロパティなど)が保持しているオブジェクトに設定されている場合、どのような場合にコントロールがオブジェクトのコピーを作成しますか(その場合、私は気をつけて、 )、そしてどのような場合にコントロールが渡されたオブジェクトを使用し続けることを期待していますか?私のドリフターがあれば、コントロールが渡されたオブジェクトの所有権を取るべきかどうかを指定する方法がありますが、存在しないので、何をすべきですか? – supercat

+0

@supercat:文書には、オーナーシップに関するルールが表示されます。しかし、少なくとも、コントロールがFontを参照している間は、それを破棄しないでください。しかし、私はコントロールが処分されたときにフォントを処分することを期待していますが、わかりません。 –

1

ファイナライザは、クリーンアップが必要なため、特にクラスに組み込まれています。クリーンアップするオブジェクトが大量であるか少量であるかにかかわらず、クリーンアップするのがよい方法です。

GCは独自の疑似心を持つように作られました。オブジェクトを適切に処分することで、GCは自分が行ったことを行うことができます。

しかし、多数のフォントオブジェクトを作成してそれらをすべて破棄している場合は、適切な世代(おそらく世代0)でGCを頻繁に呼び出すと、GCクリーンアップを頻繁に開始すると効果的です多数のインスタンス化している他のオブジェクトの種類によって異なります。あなたの目標は、あなたが高齢の世代に昇進することから非常に長い間使用していないことを知っているオブジェクトを維持することです。これにより、GCのジョブは平均で&となります。

あなたの最高の判断を使用すれば、大丈夫です。しかし、ファイナライザを持つオブジェクトは、通常の方法で処理してください。

2

の処分の重要度はどれですか、、本当ですか? IMHOこのような質問をすると、コードにデザイン上の問題があるように思えます。あなたはもう必要のないものを処分すべきです。これは責任あるプログラミングと呼ばれています。あなたの問題へ

考えられる解決策:

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

  • はフォントキャッシュクラスを実装 - 代わりにすべてのコードの上にnew演算子を使用して新しいFontオブジェクトを作成するのではなく、希望Fontを取得するには、このクラスを使用します。可能であれば、クラスは既存のフォントを再利用するロジックを持つことができます。または、最後の10個のフォントをメモリに保持し、他のフォントを破棄します。キャッシュのためにIDisposableを実装します。これは、アプリのライフサイクルで一度呼び出されます。

+0

フォントがもう使用されていないとき、フォントキャッシュクラスはどのように知っていますか?フォントをキャッシュに「戻す」必要がありますか? – Arafangion

+0

はい、フォントが必要ないことを伝える方法が必要です。私は通常、 'IDisposable'を実装する' Lease'クラスを使ってこれを行い、 'Dispose()'メソッドではキャッシュにアクセスして参照カウントを減らすよう指示します。同じパターンを工場で使うことができます。 –

+0

これは正方形に戻っていないのですか?しかし、少なくともあなたはおそらく高価なフォントを管理するマネージャーを持っていますが、それは疑問を抱きます。コンストラクタ/ファクトリとガベージコレクタが大多数状況の? – Arafangion

-2

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

関連する問題