2

このアプリにはメモリ リークがあり、ブラウザが頻繁にクラッシュします。アプリの機能の 1 つを繰り返し開いたり閉じたりすることで、メモリ使用量をかなり迅速に増やすことができます。ANTS Memory Profiler を使用して、アプリのコードが直接インスタンス化または参照しているとは思えない、不思議な成長中の辞書を見つけました。誰でもこの辞書への洞察、および/またはリークを止めるために次に何をすべきかの提案を提供できますか?

プロファイラーによると、アンマネージ メモリが最も急速に増加しています。また、「メモリの断片化により、割り当て可能なオブジェクトのサイズが制限されています」または「メモリの断片化が、割り当て可能な最大オブジェクトのサイズに影響を与えています」というメモリの断片化に関する警告が表示されることもあります。

大きなオブジェクト ヒープの最大のオブジェクトは、Dictionary<IntPtr, Object>ほとんどが WeakReferences を含む によって使用される配列です。このディクショナリが大きくなるにつれて、内部配列を再割り当てする必要があり続けると思います (ここの「備考」セクションで述べたように)。GC は LOH を圧縮しないため、フラグメンテーションが発生することになります。

ディクショナリ キーが IntPtrs であるため、このディクショナリがアンマネージ メモリの増加につながっているのかも疑問です。Tess Ferrandez のブログ投稿を参考にして DebugDiag を数回実行しましたが、分析方法がわからない興味深い情報がたくさん得られます。基本的に、メモリ割り当ての大部分は と によって行われnpctrl!CWindowsServices::OSMemoryAllocateていcoreclr:CExecutionEngine::ClrVirtualAllocます。おそらく、誰かが役立つと思われる場合は、メモリ不足の分析や .dmp ファイルを利用できるようにすることができます。

[更新]これはおそらく ManagedPeerTable だと思います。以下の更新も参照してください。[/アップデート]

以下はANTSのスクリーンショットです。1 つ目は 1 つのセッションからのもので、残りはすべて別のセッションからのものです。

メモリの断片化

メモリ変更の概要

サイズの変化が最も大きい LOH の型は、ディクショナリ エントリの配列です。

大きなオブジェクト ヒープ上のオブジェクトの一覧

ディクショナリ エントリによって参照されるもののリストを次に示します。そのほとんどは WeakReference インスタンスです。

ディクショナリ エントリによって参照されるオブジェクト

これらのエントリを含むディクショナリは、それ自体がオブジェクト配列内に存在します。

ディクショナリ エントリの配列の保持グラフ

オブジェクト配列には、UI 関連のオブジェクトが含まれているようです。

増大するディクショナリを含むオブジェクト配列の内容

漏れやすい機能には、いくつかのカスタム コントロール、テンプレート、スタイル、および高度にカスタマイズされたRadGridViewを含む、多数の XAML が関連付けられています。次に、XAML の一部を繰り返し削除して再テストし、考えられる原因の短いリストを絞り込むことを考えています。

アップデート:

XAML を削除すればするほど、リークは遅くなります。この機能の UI 要素がクリーンアップされていないことがわかったので、次はその理由を突き止める必要があります。

MS.Internal.ManagedPeerTable 静的クラスには type のプライベート フィールドがありDictionary<IntPtr, object>、それがここに表示されているに違いありません。どうやら、管理されていないオブジェクトと管理されているオブジェクトの間のリンクを維持するために使用されているようです。(下部にあるこのリンクも参照してください。) したがって、XAML 内の要素が少ない場合、テーブルとそれが参照するアンマネージ メモリの量の両方がよりゆっくりと増加することは理にかなっています。

4

1 に答える 1

0

リークを見つけ、最新バージョンの Telerik RadControls にアップグレードして修正しました。RadTreeView にメモリ リークがありましたが、これは2012 年第 3 四半期の SP1 リリースで修正されました。RadTreeView は UI のメイン UserControl への間接参照を持っていたため、UI のすべてのコントロールとリソースもメモリ内にぶら下がっていました。

前: UI から RadTreeView を削除する前のプライベート バイトのグラフ

後: UI から RadTreeView を削除した後のプライベート バイトのグラフ

また、LOH のディクショナリとアンマネージ メモリの両方が、以前のように増加していません。ディクショナリは ManagedPeerTable で使用されるものだと思いますが、GC ルートとしてではなく、オブジェクト配列内に表示されたことには驚きました。

于 2013-03-08T14:47:48.770 に答える