WPF工具包图表控制内存泄漏 [英] WPF Toolkit Charting Controls Memory Leak

查看:113
本文介绍了WPF工具包图表控制内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在XAML中创建折线图空间,如下所示,以在X轴上显示21个点(0-20),而Y轴为0-1100.

I am creating a line chart space in XAML as follows to display 21 points (0-20) on the X axis and the Y axis is 0 - 1100.

<my:Chart Canvas.Top="10" Canvas.Left="10" Name="liveData" Margin="0,0,14,67" BorderBrush="Snow" IsEnabled="True">
  <my:Chart.Axes>
    <my:LinearAxis Cursor="Cross"  Interval="1" Location="Auto"  Maximum="20" Minimum="0" Orientation="X" SeriesHost="{x:Null}" ShowGridLines="True" Title="Latest Data Points" />
      <my:LinearAxis Cursor="Cross" Interval="100" Location="Auto"  Maximum="1100" Minimum="0" Orientation="Y" SeriesHost="{x:Null}" ShowGridLines="True" Title="ADC Value"/>
      </my:Chart.Axes>
        <my:Chart.Series>
          <my:LineSeries Title="ADC" IndependentValueBinding="{Binding Path=Key}" DependentValueBinding="{Binding Path=Value}" TransitionDuration="00:00:00.0000010">
          </my:LineSeries>
            <my:LineSeries Title="OverLoad" IndependentValueBinding="{Binding Path=Key}" DependentValueBinding="{Binding Path=Value}" TransitionDuration="00:00:00.0000010">
            </my:LineSeries>
          </my:Chart.Series>
        </my:Chart>




我正在做的是每20毫秒通过虚拟COM端口(USB-RS232)读取温度传感器,然后将该数据写入txt文件.很好.

我现在有一个复选框,如果用户勾选该复选框,该图使图形(如上)可以更新实时".勾选时会导致问题.

它的工作方式如下,
1.将温度写入到发布事件中断的串行端口中.
2.检查数据并将其写入文件
3.有一个计数器对从温度传感器传入的数据量进行计数,查找成批的5.将来自温度传感器的所有5个数据点都写入txt文件,但是第5个触发线程如下:




What I''m doing is reading a temperature sensor through a virtual COM port (USB-RS232) every 20mS and I write that data to a txt file. That works fine.

I now have a checkbox that enables the graph (as above) to update ''live'' if the user ticks the box. This causes problems when ticked.

The way it works is as follows,
1. the temperature is written to the serial port posting an event interupt.
2. the data is checked and written to a file
3. there is a counter counting the amount of data coming in from the temperature sensor, looking for batches of 5. All of the 5 data points from the temperature sensor are written to the txt file, however the 5th triggers a thread as following:

globalArray[20] = latest_temp_data;
if (liveGraphUpdate == 0)
{
   Dispatcher.Invoke(DispatcherPriority.Send, new UpdateGraph(LoadLineChartData)); // Update live graph
   liveGraphUpdate = refreshRate; // resets the data in counter
}



现在调用的方法如下:



Now the method that is called is as follows:

private void showColumnChart()
{
  List<KeyValuePair<int, int>> valueList = new List<KeyValuePair<int, int>>();
  valueList.Add(new KeyValuePair<int, int>(0, globalArray[20]));
  valueList.Add(new KeyValuePair<int, int>(1, globalArray[19]));
  valueList.Add(new KeyValuePair<int, int>(2, globalArray[18]));
  .....
  valueList.Add(new KeyValuePair<int, int>(20,globalArray[0]));

  ((LineSeries)liveData.Series[0]).ItemsSource = valueList;

  LiveGraph = null; // clear space



  //shift by 1
  for (int i = 0; i < 20; i++)
  {
      globalArray[i] = globalArray[i + 1];
  }
}




因此,代码按照预期的方式运行,但是随着时间的推移它会变得故障,图形停止实时响应,而且我注意到,使用系统管理器,程序在运行后一个线程时便开始使用所有系统内存. >
从线程返回后,似乎没有释放任何内存.有什么建议吗?

提前非常感谢.




So, the code performs as it is supposed to, but it becomes glitchy after time, the graph stops responding realtime and I have noticed that using system manager the program begins to use all the system memory when it runs the latter thread.

It seems I am not freeing any memory after a return from the thread. Any suggestions??

Many thanks in advance.

推荐答案

请参阅我对问题的评论.无法看到泄漏,因为根据定义,泄漏是整个应用程序的属性(更确切地说是应用程序域System.AppDomain).如果显示代码片段,则可以告诉这里没有数据泄漏",也可以告诉可能存在数据泄漏;这取决于代码的其余部分".

您的代码显示出第二种可能性.如果您要重复在代码片段中将项目添加到列表中,则最终应重复删除这些项目.你在哪里做?名称showColumnChart本身很吓人.如果每次需要显示某些内容时在某处添加一些数据,这已经是错误的.

基本上就是这些.只需分析内存的循环并确保从某种情况开始,内存消耗不会随着时间的增长而增加,无论对任何可能的操作重复执行某些操作多少次.例如,如果用户通过打开越来越多的窗口直到内存耗尽而手动创建越来越多的资源,则这不是内存泄漏.当用户关闭所有这些窗口时,就会发生内存泄漏,但是构造的对象不会失去它们的可达性( http://msdn.microsoft.com/zh-我们/library/gg145035.aspx [ ^ ].

—SA
Please see my comment to the question. It is not possible to see the leak, because, by definition, the leak is the property of the whole application (more exactly, the Application Domain, System.AppDomain). If you show the fragment of code, one can either tell "there is no data leaks here", or "there can be a data leak; it depends on the rest of the code".

You code shows the second possibility. Is you add items to the list in your fragment of code repeatedly, you should eventually remove those items repeatedly. Where do you do it? The name showColumnChart itself is scary. If you add some data somewhere every time you need to show something, this is already wrong.

That''s basically all. Just analyze the circulation of your memory and make sure that the memory consumption is not growing with time starting from certain condition, not matter how many times some operations are repeated for any possible operations. If, for example, the user creates more and more resources manually by opening more and more windows until memory is exhausted, this is not a memory leak. The memory leak happens when the user closes all those windows, but the constructed objects do not loose their reachability (http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Reachability_of_an_object[^]) and thus are never garbage-collected.

Now, I can clearly see that you are not well familiar with collection types and misuse them, as well as the array. Why using KeyValuePair as the element of List? The KeyValuePair type is used to return the key or value while iterating though key-accessed associative containers like Dictionary. You could create your own structure.

Why shifting the elements in the array? It''s expensive and error-prone. Use Queue. Learn about usage of collections, there are not too many: http://msdn.microsoft.com/en-us/library/gg145035.aspx[^].

—SA


嗯-这是一个有点奇怪的体系结构.如果要编写此代码,则可以将图形绑定到ObservableCollection,然后将我的新项目添加到末尾(并从头开始删除该项目).这样可以避免您在此处进行的数据大量移动. [注意,我专门处理您可以轻松绑定到此处的内容-这就是为什么我推荐ObservableCollection的原因.对于无需绑定功能即可处理移位的算法,我将使用SA建议的Queue].

但是,如果您使用LineChart,请注意代码内有内存泄漏.请参阅 [
Hmm - this is a slightly odd architecture. If I were writing this, I would bind the graph to an ObservableCollection and simply add my new item to the end (and remove the one from the start). This would prevent a lot of the shifting around of data that you are doing here. [Note, I am specifically dealing with something that you can easily bind to here - which is why I recommend the ObservableCollection. For an algorithm that handles shift this without binding capabilities, I would use a Queue as SA recommends].

If you are using the LineChart though, be aware that there is a memory leak inside the code. See this[^] report. AFAIK it was never fixed.

If I were you, I would look into an alternate graph control.


这篇关于WPF工具包图表控制内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆