2014-03-19 78 views
0

我有一個Canvas,我添加了20000 Line對象如下。清除畫布和內存wpf

for (var i = 0; i < 20000; i++) 
{ 
    var l = new Line 
    { 
     X1 = 10, 
     Y1 = 10, 
     X2 = 10, 
     Y2 = 100, 
     Stroke = Brushes.White 
    }; 

    canvas.Children.Add(l); 
} 

現在讓我們假設我想刪除從Canvas這些行。我這樣做如下:

canvas.Children.Clear(); 

但這並不清除內存,它就像數據卡在那裏。因此,當我添加另一個20000 Line對象時,內存會在一段時間後爆炸。

我知道Line有開銷,我不應該在第一時間使用它,但我的問題現在在另一個區域。如何在不增加內存的情況下清除20000行的畫布並繪製新的畫布。

+1

內存是否下降或從不?你確定你沒有在任何地方參考這些線? –

+0

不,它只有在我手動使用GC.Collect()時纔會出現。 – Vahid

+0

當你說GC.collect()後內存使用量下降時,它也會自動下降。這種情況發生在垃圾回收決定是時候清理了。你只是沒有等待足夠長的時間,或者沒有使用足夠的其他記憶。 – Clemens

回答

4

你確定他們沒有去嗎?我剛剛將下面的演示應用程序放在一起。

enter image description here

XAML

<Window x:Class="WpfApplication7.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*"/> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 
     <Canvas Grid.Row="0" Name="canvas" Background="Black"/> 
     <Grid Grid.Row="1"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition/> 
       <ColumnDefinition/> 
      </Grid.ColumnDefinitions> 
      <Button Grid.Column="0" Content="Add" Name="btnAdd" Click="btnAdd_Click" /> 
      <Button Grid.Column="1" Content="Remove" Name="btnRemove" Click="btnRemove_Click"/>    
     </Grid> 
    </Grid> 
</Window> 

C#

using System.Windows; 
using System.Windows.Media; 
using System.Windows.Shapes; 

namespace WpfApplication7 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void btnAdd_Click(object sender, RoutedEventArgs e) 
     { 
      for (var i = 0; i < 20000; i++) 
      { 
       var l = new Line 
       { 
        X1 = 10, 
        Y1 = 10, 
        X2 = 10, 
        Y2 = 100, 
        Stroke = Brushes.White 
       }; 

       canvas.Children.Add(l); 
      } 
     } 

     private void btnRemove_Click(object sender, RoutedEventArgs e) 
     { 
      canvas.Children.Clear(); 
     } 
    } 
} 

並檢查與螞蟻內存分析器(http://www.red-gate.com/products/dotnet-development/ants-performance-profiler/)的內存使用情況。

按下添加按鈕並添加行後,這是行的實例列表。 enter image description here

您可以清楚地看到那一行中的行實例,然後在按下remove後可以看到行實例已完全消失,以及頂部圖形上的內存使用量下降。

enter image description here

+0

我正在檢查任務管理器中的Private Working Set,它沒有關閉。我看錯了地方嗎? – Vahid