2011-04-09 29 views
1

我有以下情况。如何最大限度地减少WPF Toolkit图表的内存使用量?

有一条线图可以一次显示10行。每行包含355个数据点。用户可以通过选择/取消选择包含数据序列的数据对象来打开和关闭每一行。

图表线看起来像这样:

<charting:LineSeries ItemsSource="{Binding DataSlot1, Mode=OneWay}" 
IndependentValueBinding="{Binding X, Mode=OneWay}" 
DependentValueBinding="{Binding Y, Mode=OneWay}" 
DataPointStyle="{StaticResource styleForDataSlot1}" 
IsSelectionEnabled="False" /> 

和我的数据从视图模型加载到每10“的数据时隙”的如下。

数据点是结构:

public struct SimpleDataPoint 
{ 
    public double X { get; set; } 
    public double Y { get; set; } 
} 

视图模型包含 “的数据时隙”:

private SimpleDataPoint[][] _dataSlots; 

和视图模型通过属性暴露数据时隙:

public SimpleDataPoint[] DataSlot1 
    { 
     get { return _dataSlots[0]; } 
    } 

当我将数据加载到插槽,我做这样的事情:

_dataSlots[freeSlot] = myDataProvider.GetPoints(); 

从插槽我做清晰的数据:

_dataSlots[slotToClear] = null; 

每个之后添加/删除数据操作的插槽我打电话

OnPropertyChanged("DataSlot1"); 

问题: 如果用户的作品很长一段时间,为图表添加和删除数据行时,我的应用程序的内存使用量很快会增加到大约100兆字节。

要查找问题是否出现在我的代码中,我注释掉了OnPropertyChanged调用。内存没有增加,当然图表没有显示任何数据。

所以我认为问题在于图表没有释放内存。在我完成_dataSlots [slotToClear] = null并且图表上相应的数据行消失后,内存不会释放,并且在完全关闭图表所在的WPF视图后内存不会恢复正常。

我试着在每个dataSlots [slotToClear] = null之后调用System.GC.Collect(),但它没有帮助。

如何强制WPF Toolkit图表释放不再显示的数据序列的内存?

+0

我会尽力重现这个问题,但我认为你宁愿使用ObservableCollection类。如果我的直觉是对的,我会说更多的信息做什么。 – vorrtex 2011-04-09 18:04:23

+1

ObservableCollection类稍微好一些,但内存泄漏仍然存在。所以我不知道还有什么要做。 – vorrtex 2011-04-09 21:10:40

+0

感谢您的想法,您对ObservableCollection有所了解。我想,问题是一些讨厌的泄漏:http://connect.microsoft.com/VisualStudio/feedback/details/571956/wpf-toolkit-lineseries-has-memory-leak因此,也许我必须看看WPF工具包源代码,看看我是否可以添加一些快速和肮脏的解决方法。或者,也许我将不得不寻找一些替代图表库... – JustAMartin 2011-04-10 08:18:23

回答

1

在我的例子中,我有1个365点的图表。该图表在其自己的用户控制ChartView中定义。主窗口看起来如此:

<Grid x:Name="root"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition /> 
    </Grid.RowDefinitions> 
    <StackPanel Orientation="Horizontal"> 
     <Button x:Name="update" Content="Update first" Click="update_Click"/> 
    </StackPanel> 
    <local:ChartView Grid.Row="1" /> 
</Grid> 

按钮的事件处理程序:

private void update_Click(object sender, RoutedEventArgs e) 
    { 
     this.root.Children.RemoveAt(1); 
     GC.Collect(); 

     this.model._dataSlots[0] = myDataProvider.GetPoints(); //this.DataContext = this.model 

     var v = new ChartView(); 
     Grid.SetRow(v, 1); 
     this.root.Children.Insert(1, v); 
    } 

的顺序如下:

  1. 取下视觉树ChartView控制。
  2. 调用垃圾收集器。
  3. 更新视图模型。
  4. 插入新的ChartView控件。

启动后应用程序消耗26Mb的内存。 第一次更新 - 32Mb。 第二次更新 - 35Mb。

但是下次更新不会超过此值,这是最大值。

随着3650点(10倍以上)的数字是:52 - > 68 - > 88

我不知道会发生什么,如果用10行,但内存消耗必须成为任何低于100MB。

+0

谢谢,刚试过你的解决方案,它似乎足够好,我会坚持下去,如果我找不到其他免费的图表图书馆。 – JustAMartin 2011-04-10 14:46:25

相关问题