2012-01-26 26 views
0

まず最初に、主題に関するさまざまな記事を読むことで、.Netの世界でメモリを解放することはタブーテーマのようなものであり、誤解されている点やそれに関する多くの議論。いずれにせよ、私は私の特定の問題に対処する答えを見たことがないと感じています。そしてここにそれは行く。WPF MVVMアプリケーションでバインドされたコレクションのメモリを解放する

MVVM Light Toolkitを使用して、ビューのDataContextにビューモデルを「注入」するWPF「TCPロガー」アプリケーションで作業しています。ビューのコントロールの1つは、コンバータを使用してObservableCollectionの "LogEntries"にバインドされた "ログ" TextBoxです。このTextBox/ObservableCollectionコンボは、アプリケーションが閉じられずに何日間も実行されている可能性があるため、何千ものアイテムで満たされる可能性があります。

<Window ... DataContext="{Binding Source={StaticResource Locator}, 
            Path=PortListenerVM}"...> 

<TextBox IsReadOnly="True"> 
    <TextBox.Text> 
     <MultiBinding Converter="{x:Static l:Converters.LogEntryCollectionToTextConverter}"> 
      <Binding Path="LogEntries" Mode="OneWay"/> 
      <Binding Path="UseTimeStamp"/> 
      <Binding Path="LogEntries.Count" Mode="OneWay" /> 
     </MultiBinding> 
    </TextBox.Text> 
</TextBox> 

とVMで:

// The MVVM Light Toolkit part 
public class ViewModelLocator 
{ 
    static ViewModelLocator() 
    { 
     ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); 
     SimpleIoc.Default.Register<PortListenerViewModel>(); 
    } 

    public PortListenerViewModel PortListenerVM 
    { 
     get 
     { 
      PortListenerViewModel portListenerVM = 
       ServiceLocator.Current.GetInstance<PortListenerViewModel>(); 
      return portListenerVM; 
     } 
    } 
}  

// The damned collection which hogs memory 
public ObservableCollection<LogEntry> LogEntries { get; set; } 

// The command which should work wonders by releasing memory 
public void ClearLog() 
{ 
    this.SelectedListenerFromObject.LogEntries.Clear(); 
    this.SelectedListenerFromObject.HasTooManyLogEntries = false; 
} 

だからどのように、私はこれまで説明してきたものを説明するために

は、ここで我々が最も、コードを愛するもののビットがあります楽観的な人なら、私は、ガベージコレクタが仕事をした直後にClearメソッドが必要なメモリを解放することを期待していました。いいえ。コレクションを「ヌル化」し、GC.Collectにも何もしませんでした。私はその後、何か他のものがまだコレクションへの参照を持っているなら、それは何ももたらさないことを発見しました。

私は今、私の質問の要点に来ています。まず、誰がLogEntries Collectionへの参照を保持しているのかを知るにはどうすればいいですか?第2に、ViewのDataContextが原因である可能性があります。そうであれば、Collectionへの参照をリリースするにはどうすればよいですか(私はToolkitのViewModelLocatorを使用しています)。

私の質問の2番目の部分は、タスクマネージャが明らかに正確なメモリ使用量を報告しないため、私のアプリケーションがどれくらいのメモリを食べているかを評価する最も良い方法は何でしょうか?私はSystem Explorerを使っていますが、これはタスクマネージャとは異なる数字を示していますが、信頼できるものもありますか?

答えて

1

おそらく問題はありません。 GCは非常に怠惰で、タスクマネージャはGCが実際に使用しているものとは異なる割り当てられたメモリを表示します。 GCは、ディスポーザブルリスト内のオブジェクトを持っているかもしれませんが、ちょうどまだそれにポイントがありません。

100,000アイテムを読み込み、コレクションをクリアするテストを作成します。一晩中実行しておきます。

+0

アイデアをありがとう、私はそれを試してみます。 – Fueled

+0

100,000アイテムをロードしてクリアしてから18時間後、システムエクスプローラのMem Usageは、クリア前に156'520 Kから128'980 Kになります。開始メモリの使用量は約58,000Kです。これは実際に解決策ではありません。 – Fueled

関連する問題