自動インスペクションメント
dotMemory はスナップショットを自動的に分析し、多くのメモリの問題を検出できます。
文字列重複
既存のものを再利用するのではなく、同じ値を持つ文字列を繰り返し作成することは、メモリを無駄にします。 dotMemory は重複した文字列を検出し、無駄なメモリ量を示します。
オブジェクトを分析するには
インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトセットをダブルクリックします。
問題を解決するには
同じ値を持つ文字列が大量のメモリを浪費したり、大量のトラフィックを生成したりする場合 (たとえば、アプリがテキスト入力を解析する場合) は、 文字列インターン(英語)を実装することを検討してください。
スパース配列
スパース配列は、ほとんどがゼロ要素で埋められた配列です。 スパース配列は、パフォーマンスとメモリ使用量の観点からは非効率的です。 dotMemory は、スパース配列を自動的に検出し、スパース配列によってどれだけのメモリが失われているか (ゼロ値で占められているか) を表示します。
スパース配列を解析するには
インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。
ファイナライズ可能オブジェクト
ファイナライズ可能オブジェクトは、 Finalize() メソッドを使用してアンマネージリソースを解放するオブジェクトです。 このパターンを使用する問題は、まず、ファイナライズ可能なオブジェクトの寿命が少なくとももう 1 回 GC サイクルだけ延長され、2 番目に、 Finalize() メソッドを実行するファイナライズスレッドが予期せず実行されることです。 これにより、解放されたリソースをできるだけ早く回収したい場合や、突然パフォーマンスが低下する可能性がある場合には、問題が発生する可能性があります。 dotMemory は、ファイナライズのためにキューに入れられたすべてのオブジェクトと、 前のスナップショット以降にファイナライズされたオブジェクトを検出して表示します。
ファイナライズ可能オブジェクトを分析するには
問題を解決するには
問題を引き起こすタイプの
IDisposableインターフェースを実装し、そのDispose()メソッドを介してすべてのアンマネージリソースを解放します。 破棄パターンの詳細については、「マイクロソフトラーン 」を参照してください。
イベントハンドラーのリーク
このようなリークは、オブジェクト (リスナーと呼びます) を他のオブジェクト (ソースと呼びます) のイベントにサブスクライブするときに発生します。 例: Timer1.Tick += OnTimer; サブスクリプション中に、ソースオブジェクトはリスナーオブジェクトのイベントハンドラーへの参照を取得します。 リスナーを削除すると、この参照によりガベージコレクションが実行されなくなります。 dotMemory は、イベントハンドラーで参照されているが、対応するイベントからサブスクライブ解除されていないオブジェクトを自動的に検索します。
オブジェクトを分析するには
インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。
問題を解決するには
リスナーが不要になったときに、そのイベントからリスナーの登録を解除します。 例:
Timer1.Tick -= OnTimer;
WPF バインディングリーク
WPF データバインディングパターンに違反すると、メモリリークが発生することもあります。 ソースオブジェクトのプロパティにデータバインディングを実行すると、バインディングターゲットオブジェクトはプロパティ変更通知のリッスンを開始します。 プロパティが DependencyProperty オブジェクトではなく、ターゲットオブジェクトが INotifyPropertyChanged インターフェースを実装していない場合、ソースオブジェクトと、ソースオブジェクトが参照するすべてのオブジェクトでメモリリークが発生する可能性があります。 dotMemory は、このようなバインディングパターン違反を検出し、この種類のリークを引き起こす可能性のあるオブジェクトのリストを表示します。
オブジェクトを分析するには
インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。
問題を解決するには
ソースオブジェクトに
INotifyPropertyChangedインターフェースを実装させるか、ClearBindingメソッドを使用してバインディングを削除します。
WPF コレクションバインディングリーク
このリークは、上で説明した WPF バインディングリークに似ています。 INotifyCollectionChanged インターフェースを実装していないコレクションへのバインディングがある場合、WPF はこのコレクションへの強い参照を作成します。 その結果、アプリケーションの存続期間中、メモリ内に残ります。 dotMemory は、このようなオブジェクトを検出して表示します。
オブジェクトを分析するには
インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。
問題を解決するには
ソースコレクションが
INotifyCollectionChangedインターフェースを実装するようにします。 別の方法は、すでにINotifyCollectionChangedインターフェースを実装しているため、ObservableCollectionコレクションを使用することです。
依存関係プロパティのリーク
このようなリークは、イベントハンドラーのリークと同じ理由で発生します。 ガベージコレクターは、 RemoveValueChanged メソッドを使用してサブスクライブ解除されるまで、 AddValueChanged メソッドを通じて DependencyProperty の変更でサブスクライブされたオブジェクトを収集しません。 dotMemory は、このようなオブジェクトをすべて検出して表示します。
オブジェクトを分析するには
インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。
問題を解決するには
サブスクライブされたオブジェクトの存続期間が終了したら、
RemoveValueChangedメソッドを使用してサブスクライブ解除を処理します。
x:Name WPF リーク
このようなリークは、次の WPF の特有の挙動によって発生します。WPF は、XAML で宣言されており x:Name ディレクティブを使用している UI 要素への強いグローバル参照を作成します。 例えば:
そのように宣言された要素を動的に削除しても、その要素はメモリ内に残ります。
オブジェクトを分析するには
インスペクションヘッダーのリンクをクリックするか、リスト内の特定のオブジェクトをダブルクリックします。
問題を解決するには
リークを解消する方法の 1 つは、XAML の代わりに C# コードで UI 要素を宣言することです。 別の方法は、UI 要素を削除するときに、親コントロールの
UnregisterNameメソッドを呼び出すことです。 例:this.UnregisterName("myControl1");