0

最近、WPFプロジェクトで深刻なメモリリークに気づきました。プロジェクトを単純化すると、ログインフォームとメインフォームがあります。メインフォームには、約30個のユーザーコントロールと3個のボタンで構成される1個のユーザーコントロール、3個のボタンとInfragisticsデータグリッドを持つ1個のユーザーコントロールがあります。私はバックグラウンドワーカーを使用して、データグリッドに対してのみ30秒ごとにDBにクエリを実行します。

main form.closedを使用してメインフォームからログアウトし、ログインウィンドウを再起動した後、ANTSメモリプロファイラー7で測定された6〜7 MBの増加があることに気付きました。未登録のイベントハンドラーがある場合でも、変数をnullに設定します。 GC.Collect()と呼ばれ、メモリリークは同じです。私の質問は次のとおりです。1。wpfウィンドウを閉じてもメモリとリソースが解放されないのはなぜですか。ANTsプロファイラーでウィンドウを閉じた後も、多くの文字列(ほとんどがGUIからのもの)がまだメモリに残っていることがわかります。2.リソースイベントセッターによって定義されたイベントの登録を解除する必要がありますか?XAMLで宣言されたイベントの登録を解除する必要がありますか?3. WPFのメモリリークから、GC.Collect()を使用すべきではないと言われましたが、少し改善されています。使ってみませんか?

4

3 に答える 3

2

PictureBox コントロールに WindowsFormsHost を使用しているときに、同様の問題が発生しました。WF PictureBox コントロールを使用する WPF ウィンドウを完全に解放できませんでした。そのため、サブウィンドウを再度開くたびに約 10 MB 増加しました。WPFウィンドウを閉じるときにWFHオブジェクトをnull化し始めたため、問題は解決しました。そのようなものを使用する場合は、すべての WF コントロールをクリアしてください。

于 2012-10-16T22:50:25.147 に答える
0

場合によります。WPFのユーザーコントロールは本質的に破棄されないため、機能をオーバーライドして、次のコマンドでコントロールで許可する必要があります。

http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx

ただし、SlimGGが提案するように、少なくとも1回はGC.Collect()を実行する必要があります。

ほとんどの場合、ガベージコレクターを直接呼び出すことは、特に制御のためではなく、廃棄のためにキューに入れられたすべてのオブジェクトに対して呼び出されるため、悪い習慣と見なされます。

于 2012-05-29T22:08:05.550 に答える
0

デバッガーに侵入し、これをイミディエイトウィンドウに入力します。

.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll

sos.dllへのパスは異なります。正しいパスを見つける方法は、[モジュール]ペインでmscorwks.dllを探すことです。それがロードされる場所はどこでもsos.dllの正しいパスです。

次に、次のように入力します。

System.GC.Collect()

これにより、到達できないものが確実に収集されます。次に、次のように入力します。

!DumpHeap -type <some-type-name>

これにより、既存のすべてのインスタンスのテーブルとアドレスが表示されます。次のように、インスタンスを存続させているものを見つけることができます。

!gcroot <some-address>

もともとダニエルが答えた

于 2012-05-29T17:35:50.937 に答える