4

クライアントのリッスンを開始する前に、いくつかのデータを処理する必要があるサーバーアプリケーションを作成しました(これは非常に重いプロセスです)。その結果、1回しか使用されないメモリ(約30MB)が割り当てられます。

ガベージコレクションを強制するメリットはありますか?またはGCにその仕事をさせますか?

また、.NET 3.5を使用する必要があります。ガベージコレクションによってスレッドが中断されることがわかっている限り、ガベージコレクターを強制するようになりました。

4

3 に答える 3

4

OK、ガベージコレクションはまだヒューリスティックであり、一般的に可能な限り最善の推測を行おうとしていますが、特定の時間よりもよく知っているという正当な主張がある可能性があります。

たとえば、アセットがたくさんあるゲームを考えてみましょう。新しいゾーンに切り替えると、ロード画面が表示され、新しいデータのロードが開始され、古いデータへの参照が解放されます。しきい値に達していないため、まだ収集されませんが、ゲームを表示するためにフレームごとに小さなマトリックスを作成し始めるとすぐにヒットする可能性があります。そうすると、(おそらく目立つ)何百メガものデータをアンロードし、他のすべてを移動してキューを圧縮しているときに、途切れます。

新しいアセットが読み込まれた後、代わりに強制的に収集できるようになりました。ユーザーはすでに「アイドル」モードになっていて、プログレスバーを見つめているため、少し途切れることに気付かず、ゲームは全体的にスムーズに見えます。

本当の秘訣は、いつ干渉するか、いつ干渉しないかを知ることです。疑わしい場合は、そうしないでください。その収集は関係なく行われ、より頻繁に行われると、アプリケーションがより不安定に見えるだけになります。それを「隠す」ための何かが必要です。たとえば、プログレスバーでアプリケーションをロックし、最終的なオブジェクトを大量に生成する長いタスクのように、ゲームのロード画面だけを思いつくことができますが、YMMVです。

于 2012-07-19T14:23:13.867 に答える
1

マネージド言語のポイントの一部は、(おそらく)ガベージコレクションについて心配する必要がないということです。ガベージコレクターを手動で呼び出すことが役立つ非常に特殊な状況のみがあり、これはほぼ確実にその1つではありません。

ここでは、GCの背後にあるセマンティクスのいくつかと、それを遅くするのではなく速くする理由について読むことができます。これは、何が起こっているのかを知っているので、理論的には良い読み物かもしれません。

それまでの間、特定の問題については、 IDisposableインターフェイスを確認する必要があると思います。大きな特定のオブジェクトがあり、心配している場合は、IDisposableインターフェイスを実装すると、作業をusingステートメントでラップできます。これにより、オブジェクトを使い終わった瞬間にオブジェクトが破棄されることが保証されます。その特定のコインの裏側では、その大きなオブジェクトへのアクティブで開いたハンドルがあることが保証されているため、usingステートメントが終了するまでGCによってピックアップされることはありません。

これはおそらく、GCを手動でねじ込むよりもはるかにうまく問題に対処します。これは、設計上、プログラマーを終わらせるためのブラックボックスのようなものです。

于 2012-07-19T14:23:42.917 に答える
0

その30MBのメモリをどのように割り当てるかはわかりませんが、それは非常に重要です。アンマネージメモリを割り当てている場合、GCはそれを認識しません(ただし、GC.AddMemoryPressureメソッドを使用して割り当てることができます)。その場合、アンマネージメモリを処理するクラスにIDisposableを実装し、オブジェクトの処理が完了したら、明示的にDisposeを呼び出す必要があります。

管理対象メモリを割り当てる場合は、次の場合を除いて、GCに作業を任せてください。

  • オブジェクトを使い終わった後は、常にアクティビティが落ち着くことがわかります。
  • GCが後の時点でパフォーマンスの問題を引き起こしているという証拠を実際に観察しました。
于 2012-07-19T14:30:17.473 に答える