2014-03-19 80 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