私は VC++ MFC 6.0 で書かれたアプリケーションを持っています。最近、vs2008 でコンパイルして .NET 3.5 にアップグレードし、マネージドおよびアンマネージド環境を使用していくつかの WPF アプリケーションを追加しました。基本的にwin32ウィンドウでWPFをホストしています。WPF アプリ ウィンドウを開くと、メモリが 1KB/10 秒のように増加し続けます。.NET メモリ プロファイラと Ants メモリ プロファイラを使用してみました。しかし、どちらもリークを検出するのに役立ちません!! ホストされている WPF アプリケーションからすべての WPF コントロールを削除しました。フレームだけのページが含まれています。しかし、それでもリークが発生します!! アプリケーションメモリが増加する原因を教えてください。
3 に答える
まず、マネージ メモリ リークかネイティブ メモリ リークかを判断する必要があります。
これを行うには、次の PerfMon カウンターを使用します。
- プロセス/プライベート バイト、
- .NET CLR メモリ/すべてのヒープのバイト数、
- .NET CLR LocksAndThreads/現在の論理スレッドの数。
1 が増加しているのに 2 が安定している場合は、ネイティブ メモリ リークが発生しています。1 と 2 が増加している場合は、マネージ メモリ リークが発生しています。
3 が予期せず増加している場合は、スレッド スタックがリークしています。
マネージ メモリ リークが見つかった場合は、Ants、YourKit などの .NET メモリ プロファイラー ツールが役立ちます。あなたのケースでは役に立たなかったので、ネイティブリークがある可能性があります。
重要: メモリ消費量を確認する前に、ガベージ コレクタを手動で呼び出してください。十分なメモリ負荷がない場合、GC は実行されず、プロセスのメモリが増加します (この特定のケースではリークではありません)。次のように GC を呼び出します。
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
さて、いくつかの魂の検索の後、リークは実際にはフレームワークのバグによるものであることがわかりました. 詳細については、これを読んで ください http://social.msdn.microsoft.com/Forums/zh/wpf/thread/5b9ae245-9067-4ca4-b846-180db9f7bde5
この記事では、WPF のメモリ問題の一般的な原因について説明します。一読の価値があるかもしれません。
メモリプロファイラーでリークを見つけようとする試みについては、ANTS で次のことを試してください。
1) 1 ~ 2 分間隔で 2 つのスナップショットを作成します (毎回スナップショットを作成する前に、プロファイラーが自動的にガベージ コレクションを実行します)。
2) ベースライン スナップショットがスナップショット 1 に設定され、最後のスナップショットがスナップショット 2 に設定されていることを確認します。
3) クラス一覧に移動します。
4) [基本フィルター] の下で、[現在のスナップショットから新しいオブジェクトのみを表示] を選択します。
5) 最大のクラスを強調表示し、インスタンス リストに移動します。
6) インスタンスの 1 つについて、そのインスタンスをメモリに保持している参照のチェーンを示すインスタンス保持グラフを開きます。
7) 運が良ければ、あるべきではない何かにつかまっているオブジェクトが表示されますが、これを修正することができます。そうでない場合は、手順 5 と 6 を繰り返しますが、別のクラス/インスタンスを選択します。