2011-04-21 110 views
3

我們的應用程序中存在一個問題,當用戶控件 被卸載時內存未被釋放。這將增加從40MB開始的內存,並以200MB或更多的內存結束。WPF不釋放內存

爲了模擬這一,

  1. 我創建具有主窗口和一個用戶控制
  2. 裝載1000個對象到被放置在用戶控制
  3. 一種渦旋一個WPF數據網格一個WPF項目查看器放在主窗口中
  4. 用戶控件在此滾動查看器中加載一旦點擊顯示按鈕
  5. 用戶控件從滾動viwer的內容中刪除一次關閉按鈕被點擊

一旦我與任務管理器檢查,在1000個對象加載到網格之前,內存消耗是14MB。一旦通過點擊顯示按鈕加載它,它就會增加到70MB。但是當我點擊關閉按鈕從窗口中刪除用戶控件時,內存只能減少到67MB。它不應該減少到14BMB或接近那個?

當我使用ANTS內存分析器進行檢查時,它顯示即使從窗口中刪除用戶控件後,1000個對象仍保留在內存中。當用戶控件從窗口中移除時(Scroll查看器的內容屬性設置爲空),垃圾收集器是否應該釋放這些對象?

以下是我用於此的代碼。我沒有使用任何樣式,數據模板或任何第三方控件,只使用WPF DataGrid控件加載數據。

用戶控制碼後面

public partial class UserControl1 : UserControl,IDisposable 
{ 
    List<TestClass> list = null; 

    public UserControl1() 
    { 
     InitializeComponent(); 
    } 

    public void Dispose() 
    { 
     BindingOperations.ClearBinding(dgList, DataGrid.ItemsSourceProperty); 
     list.Clear(); 
     GC.Collect(); 
    } 

    private void UserControl_Loaded(object sender, RoutedEventArgs e) 
    { 
     list = new List<TestClass>(); 

     for (int i = 0; i < 1000; i++) 
     { 
      TestClass obj = new TestClass(); 
      obj.Name = "test name"; 
      obj.Age = 34; 

      list.Add(obj); 
     } 
     dgList.ItemsSource = list; 
    } 

} 

public class TestClass 
{ 
    public string Name { get; set; } 
    public int Age { get; set; }  
} 

主窗口代碼後面

public partial class MainWindow : Window 
{ 
    UserControl1 control = null; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void btnClose_Click(object sender, RoutedEventArgs e) 
    { 
     control.Dispose(); 
     scwContent.Content = null; 
     control = null; 

    } 

    private void btnShow_Click(object sender, RoutedEventArgs e) 
    { 
     control = new UserControl1(); 
     scwContent.Content = control; 
    } 
} 

感謝。

回答

0

你爲什麼要調用GC?這不需要

變化

for (int i = 0; i < 1000; i++)   
{    
    TestClass obj = new TestClass(); 
    ... 

TestClass obj; 
for (int i = 0; i < 1000; i++)  
{   
    obj = new TestClass(); 
    ... 

您可以設置列表對象爲空.. 閱讀理解爲對象設置爲null Setting an object to null vs Dispose()

0

的垃圾收集器僅在需要內存時收集,而不是在引用設置爲空時收集。

(僅限特例:致電GC.Collect()