4

アプリケーションの背景

私たちのプラットフォームは、クリックワンスのWPFアプリケーションです。ナビゲーションメニュー構造を含む「シェル」があり、独自のカスタム「ページ」クラスをホストしています。新しいページに移動すると、シェルのコンテンツが(基本的に)スワップアウトされます。

問題

それで、私は非常に大規模なソフトウェアプロジェクトに取り組んでいる会社で働いています。メモリの問題を見つけたコードがたくさんあります。

問題は、イベントが配線されていて、配線されていない場所がアプリケーションにたくさんあることです。開発者がこれを行った理由はわかりません。ユーザーが新しい「ページ」に移動するたびにオブジェクトがクリーンアップされることを期待していたと思います。

(このリリースでは)すべてのページをリファクタリングするオプションはありません。オブジェクトからすべての参照を削除するC#の方法はありますか?(したがって、ガベージコレクターがそのオブジェクトをそのすべての内部参照とともに破棄できるようにします)

このメモリを取り戻そうとしていますが、処理するWPFがある場合、オブジェクトがまだページ(オブジェクト参照)を参照していることを見つけるのは非常に複雑です。

視覚的および論理的なツリーを調べ、プロファイリングアプリケーションを使用して、手動で物事をクリーンアップするのに役立てました(アイデアを証明するため)。これも非常に難しいことがわかりました。

私は座って考えました。なぜオブジェクト参照を見つけるためにこのすべての作業を行うのでしょうか。閉じたときにこの「ページ」を単に「逆参照」することはできないのでしょうか。

それは私をここに連れて来ます:)
どんな助けでも大歓迎です!


更新1

コメントでは、次のことが尋ねられました。

Q:アプリはありますか。実際にメモリの問題がありますか?これらはどのように展示/検出されますか?それとも、GC2が発生するまで、このメモリはぶらぶらしていますか?–ミッチ小麦

A:メモリに問題があります。ページを離れると(ページを保持するプロパティが新しいオブジェクトに設定されます)、古いオブジェクトがガベージコレクターによって収集されることはありません。したがって、メモリは増え続けます。私たちの会社が最初からやり直した場合、このアプリケーションで。最初に確認する必要があるのは、WeakEventパターンを実装し、WPFでより多くのルーテッドコマンドを使用することです。

更新2

私は自分自身の解決策を思いつくことができました。

4

3 に答える 3

1

CLRProfiler を使用したことがありますか? これは、オブジェクトを見つけたり、それらへの参照を保持しているものを見つけたりするのに非常に適していると思います。

この「ハウツー」ページ...

http://msdn.microsoft.com/en-us/library/ms979205.aspx

... ダウンロード サイトへのリンク。

しかし、あなたの質問に対する答えは「いいえ」だと思います。「オブジェクト foo はもう必要ありません。ルート化されているかどうかに関係なく収集してください」と言う方法はありません。ルート化されたオブジェクトを収集すると、アプリにあらゆる種類の悪影響を及ぼす可能性があります。

于 2009-03-06T15:14:26.827 に答える
-1

ホール ページが、すべての基になるデータを含めて範囲外になる場合、GC はそれを収集します。最終的。ただし、そのページがまだスコープ内にあるものによって参照されている場合、ページとそのすべてのデータはメモリに残り、GC はそれを収集できません。

私の知る限り、悪いメモリ管理を修正するための簡単なボタンはありません。これは、私の意見では、参照をクリーンアップする作業を行うことだけを意味します。これにより、GC が範囲外のオブジェクトを収集しやすくなります。

GC.Collect() を呼び出して、GC のアルゴリズムを調べて、何かを収集できるかどうかを確認するように GC に提案できます。ただし、データが本当に範囲外でない限り、これは CPU サイクルを浪費する以外にはほとんど何もしません。

Phobis への質問です。あなたのアプリケーションはどのくらいのメモリを使用していますか?

編集:

.net3.5 アプリで動作する CLR Profiler 2.0 へのリンク。 https://github.com/MicrosoftArchive/clrprofiler

于 2009-03-06T14:17:11.143 に答える