Click here to Skip to main content
14,983,791 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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: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:LineSeries Title="ADC" IndependentValueBinding="{Binding Path=Key}" DependentValueBinding="{Binding Path=Value}" TransitionDuration="00:00:00.0000010">
            <my:LineSeries Title="OverLoad" IndependentValueBinding="{Binding Path=Key}" DependentValueBinding="{Binding Path=Value}" TransitionDuration="00:00:00.0000010">

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.
Updated 26-Jan-12 5:55am
Sergey Alexandrovich Kryukov 26-Jan-12 11:58am
When you do valueList.Add do you ever remove or forget the whole list. If you don't this is not event a memory leak, you just increase memory consumption without limits.
Member 8321751 26-Jan-12 13:22pm
hmmm good point - no, what would be the best way to do that?
santy143all 25-Jun-12 8:07am
youcan set timer dat after particular time it will be deleted

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 ([^]) 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:[^].

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.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900