2009-08-14 92 views
0

我在WPF/MVVM中綁定到ObservableCollection頂部的ItemsSource的TabControl。每個選項卡都有自己的集合,並與組件(如圖像,Richtextbox和用戶輸入框)進行綁定,並且一切看起來都很順利。WPF RichTextBox選項卡選擇吃掉系統內存!

但是,我注意到,每次切換選項卡時,它都會使用大約100k的系統內存,而這些內存永遠不會被回收!如果我按住ctrl-tab循環所有選項卡,我可以在一分鐘內用完200兆內存。

現在我創建了一個空白WPF應用程序,只有一個選項卡控件,並且它還爲每個選項卡開關使用內存(albiet很少)。這只是一些.NET錯誤或功能?也許它存儲麪包屑痕跡,也許它用於調試(雖然我編譯在發佈模式)。

我該如何回收我的記憶?或者更好的是,不要失去記憶切換標籤?

回答

0

很好的建議,但最終我決定一個可綁定的文本塊比richtextbox更有用和更簡單。我從來沒有發現是什麼導致了泄漏 - 但它肯定是在bindablerichtextbox代碼中(每次切換標籤時都會調用OnInitialized,這超出了我的控制範圍)。

泄漏消失了,我的應用運行更快,因爲使用了更簡單的可綁定文本塊。

1

您可能想檢查是否有任何事件處理程序被遺留。

如果您在其他控制中註冊了某個事件,garbadge收集器將不會收集不再需要的對象,因爲事件仍然可以這樣說。

所以,如果你註冊代碼的某個地方加載背後

public ParentEditor() 
{ 
    InitializeComponents(); 
    control.Loaded += OnControlLoaded; 
} 

或XAML或ParentControl

<Control Loaded="OnControlLoaded" /> 

您basicly有兩個解決方案來解決這個問題:

解決方案1 - 刪除不再需要的事件處理程序:

您可能要在卸載像這樣父控件刪除此處理程序:

public ParentEditor() 
{ 
    InitializeComponents(); 
    control.Loaded += OnControlLoaded; 

    this.Unloaded += OnParentUnloaded; 
} 

void OnParentUnloaded(object sender, RoutedEventArgs e) 
{ 
    //Remove unloaded event 
    this.Unloaded -= OnParentUnloaded; 

    //Remove event from child control 
    control.Loaded -= OnControlLoaded;   
} 

您還可以使用過程中的子控件的空載情況下..這是給你..

解決方案2 - 使用WeakEvent模式:

事件另一種解決方案將是WeakEvent圖案,它繞過這個問題。

爲什麼要實現WeakEvent模式?

聆聽事件可能導致內存泄漏 。用於收聽事件的典型技術 是使用 將處理程序附加到 源上的事件的語言特定語法。例如,在C#中, 的語法是:source.SomeEvent + = new SomeEventHandler(MyEventHandler)。

此技術創建從事件源到 事件偵聽器的強引用 。通常,爲聽衆附加一個事件處理程序 會導致 收聽者有一個對象 影響對象的生命週期(除非明確地刪除了 事件處理程序)。 但在某些情況下,你可能 希望被其他 因素,如是否 目前屬於該應用程序的可視化樹 ,而不是由 一生源的唯一控制的 監聽的對象的生命週期。每當源對象的生命週期超出 時,監聽器的對象生存期, 正常事件模式導致內存泄漏:監聽器保持 比預期長。

在這兩種情況下,好運 ..其很難找到像您所遇到的一個泄漏!

+0

謝謝你的建議 - 非常有用!但是對於MVVM,甚至不使用事件處理程序。 viewmodel對gui一無所知,只是公開gui掛鉤的命令。 – bluebit 2009-08-17 09:36:40