最近將一個開發和維護了五年的一個Winform項目進行重構,考慮到最近很流行將用戶體驗掛在嘴上,於是采用了WPF技術,希望能在外觀和體驗上有一個全新的效果。
以前使用Winform的時候內存控制得不錯,軟件使用一天下來也就100M左右,現在使用WPF,十分鍾就達到了100M,在感慨WPF的胃口之余也在思考怎樣將內存占用量降下去。
首先寫了一個測試項目,放兩個窗體。第一個窗體放一個DataGrid,里面綁定200條數據,第二個窗體放兩個測試按鈕,按鈕點擊代碼如下。
//打開20個測試窗口 List<TestWindow> windows = new List<TestWindow>(); private void Button1_Click(object sender, RoutedEventArgs e) { for (int i = 0; i < 20; i++) { var window = new TestWindow(); windows.Add(window); window.Show(); } } //關閉當前打開的測試窗口 private void Button2_Click(object sender, RoutedEventArgs e) { foreach (var item in windows) { item.Close(); } } //調用垃圾回收器,強制回收可用內存 private void Button3_Click(object sender, RoutedEventArgs e) { GC.Collect(); }
現在准備開始測試:
點擊Button1打開20個測試窗口,此時內存便達到了126M,點擊Button2,關閉所有測試窗體,內存110M,再次打開20個測試窗體,內存205M,關閉所有窗體,內存185M,條用垃圾回收,內存139M
將程序稍微改動了一下,關閉測試窗體時,將數據上下文綁定(DataContext)賦值為空,繼續測試
點擊Button1打開20個測試窗口,此時內存便達到了123M,點擊Button2,關閉所有測試窗體,內存110M,再次打開20個測試窗體,內存136M,關閉所有窗體,內存120M,條用垃圾回收,內存55M
進行了多次測試,結果數據基本一致,為了更直觀的對數據有一個比較,現將數據列表如下:
程序運行 | 打開20個測試窗體 | 關閉20個測試窗體 | 再次打開20個測試窗體 | 再次關閉20個測試窗體 | 強制垃圾回收 | |
關閉窗體時不做處理 | 17M | 126M | 110M | 205M | 185M | 139M |
關閉窗體時將DataContext賦空值 | 17M | 123M | 110M | 136M | 120M | 55M |
所以,結論只有一個,當我們使用MVVM模式綁定DataContext或是直接給列表控件綁定數據源的情況下,關閉窗體時,最好將綁定屬性賦一個空值
protected override void OnClosed(EventArgs e) { base.OnClosed(e); this.DataContext = null; }
以后會繼續博文,將親身經歷的WPF優化方案提出來,和大家一起探討。