dotMemory 2019.1ヘルプ

自動インスペクション

dotMemoryは、以下のメモリの問題を自動的に検出します。

文字列重複

既存のものを再利用するのではなく、同じ値を持つ文字列を繰り返し作成することは、メモリを無駄にします。dotMemoryは重複した文字列を検出し、無駄なメモリ量を示します。

オブジェクトを分析するには

  • インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトセットをダブルクリックします。

問題を解決するには

  • 同じ値を持つ文字列が大量のメモリを浪費したり、大量のトラフィックを生成したりする場合(たとえば、アプリがテキスト入力を解析する場合など)は、文字列のインターナリング(英語)を実装することを検討してください。

スパース配列

スパース配列は、ほとんどがゼロ要素で埋められた配列です。スパース配列は、パフォーマンスとメモリ使用の観点から非効率的です。dotMemoryは自動的に疎な配列を見つけ、それらのために失われたメモリ量(ゼロ値で占められている)を表示します。

スパース配列を解析するには

  • インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。

ファイナライズ可能オブジェクト

ファイナライズ可能オブジェクトは、Finalize() メソッドを使用してアンマネージリソースを解放するオブジェクトです。このパターンを使用する問題は、まず、ファイナライズ可能なオブジェクトの寿命が少なくとももう1回GCサイクルだけ延長され、2番目に、Finalize() メソッドを実行するファイナライズスレッドが予期せず実行されることです。これにより、解放されたリソースをできるだけ早く回収したい場合や、突然パフォーマンスが低下する可能性がある場合には、問題が発生する可能性があります。dotMemoryは、ファイナライズのためにキューに入れられたすべてのオブジェクトと、前のスナップショット以降にファイナライズされたオブジェクトを検出して表示します。

ファイナライズ可能オブジェクトを分析するには

  1. インスペクションヘッダーのリンクをクリックするか、リスト内の任意のタイプをダブルクリックします。

  2. IDisposableを実装する型だけを残すには、フィルターフィールドに #d と入力します。すべての使い捨てタイプは disposable icon アイコンでマークされています。

  3. IDisposableを実装していないタイプのみを残すには、フィルターフィールドに !d と入力します。

問題を解決するには

  • 問題の原因となるタイプの IDisposable インターフェースを実装し、Dispose() メソッドを使用してすべての管理されていないリソースを解放します。Dispose パターンの詳細については、MSDN(英語)を参照してください。

イベントハンドラのリーク

このタイプのリークは、他のオブジェクトのイベント(それをソースと呼ぶ)にオブジェクトをサブスクライブするとき(let's = listener)に発生します。例: Timer1.Tick += OnTimer; サブスクリプション時に、ソース・オブジェクトはリスナー・オブジェクトのイベント・ハンドラへの参照を取得します。リスナーを削除すると、この参照によってガベージコレクションが行われなくなります。dotMemoryは、イベントハンドラで参照されているオブジェクトを自動的に検索しますが、対応するイベントの登録を解除することはありません。

オブジェクトを分析するには

  • インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。

問題を解決するには

  • リスナーが不要になったときに、そのイベントからリスナーの登録を解除します: 例: Timer1.Tick -= OnTimer;

Wpf結合リーク

WPFデータバインディングパターンを破ると、メモリリークが発生する可能性もあります。ソースオブジェクトの一部のプロパティーにデータバインディングを実行すると、バインディングターゲットオブジェクトはプロパティーの変更通知を待機し始めます。プロパティーが DependencyProperty オブジェクトでなく、ターゲットオブジェクトが INotifyPropertyChanged インターフェースを実装していない場合、ソースオブジェクトおよびソースオブジェクトが参照するすべてのオブジェクトのメモリリークが発生する可能性があります。dotMemoryはこのようなバインディングパターン違反を検出し、このリークタイプを引き起こす可能性のあるオブジェクトのリストを表示します。

オブジェクトを分析するには

  • インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。

問題を解決するには

  • ソースオブジェクトに INotifyPropertyChanged インターフェースを実装させるか、ClearBinding メソッドを使用してバインディングを削除します。

Wpfコレクションバインディングリーク

このリークは、上記のWPFバインディングリークに似ています。 INotifyCollectionChanged インターフェースを実装していないコレクションにバインディングがある場合、WPFはこのコレクションへの強力な参照を作成します。その結果、アプリケーションライフタイム全体にわたってメモリに保持されます。dotMemoryはそのようなオブジェクトを検出して表示します。

オブジェクトを分析するには

  • インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。

問題を解決するには

  • ソースコレクションが INotifyCollectionChanged インターフェースを実装するようにします。別の方法は、既に INotifyCollectionChanged インターフェースを実装しているため、ObservableCollection コレクションを使用することです。

依存関係プロパティーのリーク

このリークは、イベントハンドラのリークと全く同じ理由により発生します。GCは、RemoveValueChanged メソッドを使用して登録解除されるまで、AddValueChanged メソッドを使用して DependencyProperty に登録されたオブジェクトを収集しません。dotMemoryはそのようなすべてのAオブジェクトを検出して表示します。

オブジェクトを分析するには

  • インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。

問題を解決するには

  • サブスクライブされたオブジェクトの存続期間が終了したら、RemoveValueChanged メソッドを使用してサブスクライブ解除を処理します。

x:WPFリークの名前

WPFは、XAMLで宣言されたUI要素への強力なグローバル参照を作成し、x:Nameディレクティブを使用します。例: < XNameTest:UserControl1 Grid.Row="0" x:Name="myControl1"/> したがって、このように宣言された要素を動的に削除しても、まだメモリに残っています。

オブジェクトを分析するには

  • インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。

問題を解決するには

  • リークを解消する方法の1つは、XAMLの代わりにC#コードでUI要素を宣言することです。別の方法は、UI要素を削除するときに、親コントロールの UnregisterName メソッドを呼び出すことです。例: this.UnregisterName("myControl1");

最終更新日: 2019年5月31日