Memory Usage keep increasing when auto scrolling chart

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
jdsu
Newbie
Newbie
Posts: 22
Joined: Tue Jun 14, 2011 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by jdsu » Fri Feb 24, 2012 5:01 am

Hi Sandra,

I installed v4.1.2012.01030 and rebuild my test app.
My test machine is running Windows 7, 32 bit.

I launch the test app and choose "2 Series". I click Start. At this time the memory shown in the Task Manager (Working Set Memory), it shows 30Mb.
1 Hour later, it shows 41Mb.
2 Hour later, it shows 60Mb.
I have attached the screen capture of the Task Manager.
(In this screen capture, I have 2 instance of the test app, one running "2 Series", another running "30 Series".)
Attachments
TChartTest-Memory-2Hr.png
TChartTest-Memory-2Hr.png (37.45 KiB) Viewed 14658 times

jdsu
Newbie
Newbie
Posts: 22
Joined: Tue Jun 14, 2011 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by jdsu » Fri Feb 24, 2012 10:43 am

Hi Sandra,

Here is another screen capture after running for 4 hours.
Attachments
TChartTest-Memory-4Hr.png
TChartTest-Memory-4Hr.png (54.8 KiB) Viewed 14577 times

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by Sandra » Wed Feb 29, 2012 5:06 pm

Hello jdsu,

I haven't forgotten you. I am done many test with your project and try to answer your asap.

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by Sandra » Wed Mar 07, 2012 1:33 pm

Hello jsdu,

Sorry for the delay.I can reproduce your problem using last version of TeeChart.Net and I suggest you follow you next advice:

The first and most important way to prevent the memory used by the application growing is removing data which is no longer used or visible. Otherwise TeeChart needs memory to store this data and you should expect memory consumption to increase. Having said that, if you are already removing unneeded data from your application and memory consumption is still growing in a uncontrolled manner it could be a memory leak in TeeChart. Moreover, Please notice that the .NET Framework doesn't free objects immediately, it's garbage collector who does that task. Therefore you may see memory consumption oscillations in your application. At this thread you'll find a more in deep discussion on garbage collector and TeeChart.

If you have any problems, please let me know.

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

jdsu
Newbie
Newbie
Posts: 22
Joined: Tue Jun 14, 2011 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by jdsu » Fri Mar 23, 2012 3:32 am

Hi Sandra,

I have modified my test application to add another Timer. This timer will be fired once every 5 seconds.
In the timer handler, I do a "GC.Collect()".

I run the test application again for 1 hour. I still see the memory keep increasing. So it seems that "GC.Collect()" does not help.

In my test application, I have an option to use 2 series or 30 series.
I noticed that the one using 2 series is using more memory then the 30 series.
Each series keep the last 1000 data point. I would expect the one using 30 series uses more memory, if we think that the memory is taken by the data points.
But it seems we may be hunting in the wrong path.

Rather then figuring out why the memory keep increasing, I would like you to propose what is the best way to use teechart to do the following.
1. A line chart with several series.
2. Each series start or data arrival may be at different time.
3. The X axis to display the time.
4. The chart should auto scroll to show the latest data point.
5. Keep the last 1000 data point for each series.
I believe the above requirement is very normal. Open a Task Manager and click the Networking tab and you can see such a line chart (of the network traffic).
This line chart will auto scroll and is time based and has several lines per chart. (See Attached Image)

Using your professional knowledge of the correct way of using TeeChart, can you give me a sample application to show me the correct way to do what is shown in the Task Manager's chart?
Attachments
TaskManagerNetworking.png
TaskManagerNetworking.png (4.59 KiB) Viewed 14511 times

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Memory Usage keep increasing when auto scrolling chart

Post by Narcís » Mon Mar 26, 2012 10:50 am

Hello,

What about the example below based on the Real-time charting article? It doesn't consume memory for me here using latest TeeChart .NET release. Does this work fine at your end? Is this what you were looking for?

Code: Select all

  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
      InitializeChart();
    }

    const int maxPoints = 10000;
    const int scrollPoints = 1000;
    const int numSeries = 2;

    private Steema.TeeChart.Styles.FastLine fastline1;

    private void InitializeChart()
    {
      tChart1.Aspect.View3D = false;
      tChart1.Legend.Visible = false;
      tChart1.Aspect.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;

      Random randomGen = new Random();
      KnownColor[] names = (KnownColor[])Enum.GetValues(typeof(KnownColor));

      for (int i = 0; i < numSeries; i++)
      {
        fastline1 = new Steema.TeeChart.Styles.FastLine(tChart1.Chart);

        //pre-assign ChartPens
        KnownColor randomColorName = names[randomGen.Next(names.Length)];
        Color randomColor = Color.FromKnownColor(randomColorName);

        Pen rPen = new Pen(randomColor);
        Steema.TeeChart.Drawing.ChartPen randomPen = new Steema.TeeChart.Drawing.ChartPen(tChart1.Chart, rPen);
        fastline1.LinePen = randomPen; 
      }

      timer1.Interval = 1000;
      timer1.Enabled = true;
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
      tChart1.AutoRepaint = false;

      double[] xVals = new double[scrollPoints];
      double[] random = new double[scrollPoints];

      for (int i = 0; i < tChart1.Series.Count; i++)
      {
        FillXArray(xVals, tChart1[0].MaxXValue());
        FillArray(random);
        
        tChart1[i].Add(xVals, random, true);
        DoScrollPoints(tChart1[i]);
        tChart1.AutoRepaint = true;
        Application.DoEvents();
      }
    }

    private void FillXArray(double[] xArray, double start)
    {
      for (int i = 0; i < xArray.Length; i++)
      {
        xArray[i] = ++start;
      }
    }

    private static void FillArray(double[] myArray)
    {
      Random y = new Random();
      for (int i = 0; i < myArray.Length; i++)
      {
        myArray[i] = y.Next();
      }
    }

    private void DoScrollPoints(Steema.TeeChart.Styles.Series series)
    {
      double tmp, tmpMin, tmpMax;

      if (series.Count > maxPoints)
      {
        tChart1.Axes.Bottom.Automatic = false;
        tChart1.Axes.Left.Automatic = false;

        // Delete multiple points with a single call.
        // Much faster than deleting points using a loop.
        series.Delete(0, scrollPoints);

        // Scroll horizontal bottom axis
        tmp = series.XValues.Last;
        series.GetHorizAxis.SetMinMax(tmp - maxPoints + scrollPoints, tmp + scrollPoints);

        // Scroll vertical left axis
        tmpMin = series.YValues.Minimum;
        tmpMax = series.YValues.Maximum;

        series.GetVertAxis.SetMinMax(tmpMin - tmpMin / 5, tmpMax + tmpMax / 5); 
      }
    }
  }
Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

jdsu
Newbie
Newbie
Posts: 22
Joined: Tue Jun 14, 2011 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by jdsu » Tue Mar 27, 2012 6:02 am

Hi Narcis,

Thanks for the sample. I have created a new test app using the given sample.
However, the X asis does not display as the elapsed time format.
Can you update the code such that the X asis shows in time format? (Elapsed time)
Attachments
TChartTest2.png
TChartTest2.png (46.17 KiB) Viewed 14502 times

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by Sandra » Wed Mar 28, 2012 1:17 pm

Hello jdsu,

I made some modifications in the Narcis code because it works with DateTimes, works fine for me and use of Memory doesn't increase. I think, you can do something as do in next lines:

Code: Select all

 public partial class Form1 : Form
    {
        DateTime dt;
        public Form1()
        {
            InitializeComponent();
            InitializeChart();
                     
            start = TimeSpan.FromMilliseconds(10);
        }

        const int maxPoints = 10000;
        const int scrollPoints = 1000; 
        const int numSeries = 2;
      
        private TimeSpan start;

        private Steema.TeeChart.Styles.FastLine fastline1;

        private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;
            tChart1.Legend.Visible = false;
            tChart1.Aspect.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;

            Random randomGen = new Random();
            KnownColor[] names = (KnownColor[])Enum.GetValues(typeof(KnownColor));

            for (int i = 0; i < numSeries; i++)
            {
                fastline1 = new Steema.TeeChart.Styles.FastLine(tChart1.Chart);

                //pre-assign ChartPens
                KnownColor randomColorName = names[randomGen.Next(names.Length)];
                Color randomColor = Color.FromKnownColor(randomColorName);

                Pen rPen = new Pen(randomColor);
                Steema.TeeChart.Drawing.ChartPen randomPen = new Steema.TeeChart.Drawing.ChartPen(tChart1.Chart, rPen);
                fastline1.LinePen = randomPen;
                fastline1.XValues.DateTime = true;
            }

            tChart1.Axes.Bottom.Labels.DateTimeFormat = "HH:mm:ss.fff";
            timer1.Interval = 1000;
            timer1.Enabled = true;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            tChart1.AutoRepaint = false;

            double [] xVals = new double[scrollPoints];
            double[] random = new double[scrollPoints];
           
            for (int i = 0; i < tChart1.Series.Count; i++)
            {
                FillXArray(xVals, start);
                FillArray(random);

                tChart1[i].Add(xVals, random, true);
                DoScrollPoints(tChart1[i]);
                tChart1.AutoRepaint = true;
           
                Application.DoEvents();
            }
            tChart1.AutoRepaint = true;
            tChart1.Refresh();
        }

        private void FillXArray(double[] xArray, TimeSpan start)
        {
            dt = DateTime.Now;
            for (int i = 0; i < xArray.Length; i++)
            {
                xArray[i] = dt.ToOADate();
                dt += start;
            }
        }
        private static void FillArray(double[] myArray)
        {
            Random y = new Random();
            for (int i = 0; i < myArray.Length; i++)
            {
                myArray[i] = y.Next();
            }
        }

        private void DoScrollPoints(Steema.TeeChart.Styles.Series series)
        {
            double tmp, tmpMin, tmpMax;

            if (series.Count > maxPoints)
            {
                tChart1.Axes.Bottom.Automatic = false;
                tChart1.Axes.Left.Automatic = false;
                series.Delete(0, 1000);
                tmp = series.XValues.Last;
                DateTime minScrollDateTime = dt.Subtract(new TimeSpan(0,0,10));
                tChart1.Axes.Bottom.Minimum = minScrollDateTime.ToOADate();
                tChart1.Axes.Bottom.Maximum = dt.ToOADate();
                // Scroll vertical left axis
                tmpMin = series.YValues.Minimum;
                tmpMax = series.YValues.Maximum;

                series.GetVertAxis.SetMinMax(tmpMin - tmpMin / 5, tmpMax + tmpMax / 5);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            tChart1.ShowEditor();
        }
    }
Can you please, tell us if previous code works as you expect?

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

jdsu
Newbie
Newbie
Posts: 22
Joined: Tue Jun 14, 2011 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by jdsu » Fri Mar 30, 2012 5:56 am

Hi Sandra,

Using your sample, it is working very good. I can run for a day without any increase in memory.
Using your latest sample, the X axis is now showing the current time.
Can you show me how to make it to display elapsed time? ie starting from 00:00:00, then 00:00:01, etc.
And in my case, there are several series. The data coming in for each series are random, some more, some less.
But the elapsed time to show on the X axis should reference to the 1st data item of the longest series.

jdsu
Newbie
Newbie
Posts: 22
Joined: Tue Jun 14, 2011 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by jdsu » Fri Mar 30, 2012 7:53 am

Hi Sandra,

In your sample, your timer is 1000ms interval. At each timer tick, you add 1000 new data point. If the Max Data Points is reached, you removed the first 1000 data points.

I wanted the timer tick to be shorter, so that the chart scrolling is smoother, I changed the timer interval to 100ms and the number of new data points to add & delete to 100.

To make the X axis shows the elapsed time, I copied the code from my own app into yours. This "ReFormatXTimeAxis() is called at the end of each Timer Tick.

Code: Select all

        private void ReFormatXTimeAxis()
        {
            // Label the series with the most number of points
            Series longestSeries = tChart1.Series[0];
            foreach (Series series in tChart1.Series)
            {
                if (series.XValues.Count > longestSeries.XValues.Count)
                    longestSeries = series;

                series.Labels.Clear();
            }
            DateTime firstValue = longestSeries.XValues.AsDateTime(0);
            for (int i = 0; i < longestSeries.XValues.Count; i++)
            {
                TimeSpan span = longestSeries.XValues.AsDateTime(i).Subtract(firstValue);
                longestSeries.Labels.Add(span.ToString());
            }
        }
After this change, the memory increase issue came back.
So my guess is, could it be due to the call Labels.Add() ??
If so, what is the correct way to do this ?

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by Sandra » Mon Apr 02, 2012 9:30 am

Hello jsdu,

The problem of Momory Usage is produced with the code you have added finally of my code to reformat the axes. I recommend take a look in this thread, where the discussion talk about of relative and absolute values and I think it can useful for you. I try it and the memory use of my computer doesn't increase.

I hope will helps.

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

jdsu
Newbie
Newbie
Posts: 22
Joined: Tue Jun 14, 2011 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by jdsu » Thu Apr 05, 2012 1:37 am

Hi Sandra,

I believe the main point is this line :
tChart1.GetAxisLabel += new Steema.TeeChart.GetAxisLabelEventHandler(tChart1_GetAxisLabel);

So this means that tChart will do a callback even ever it wants the text for the Label?
But in the Callback, the parameter : GetAxisLabelEventArgs e
Why is the property "Series" set to null?
And the property "ValueIndex" set to -1?

My Chart has many Series, how can I know which Series label is tChart asking for?
And which data item's label is it refering to since "ValueIndex" is -1 ?

So this conclude that we cannot use Label.Add() to set the Label of a Series. Correct ?

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by Sandra » Thu Apr 05, 2012 2:24 pm

Hello jdsu,
So this means that tChart will do a callback even ever it wants the text for the Label?
tChart1.GetAxisLabel = new Steema.TeeChart.GetAxisLabelEventHandler(tChart1_GetAxisLabel);
So this means that tChart will do a callback even ever it wants the text for the Label?
But in the Callback, the parameter : GetAxisLabelEventArgs e
Why is the property "Series" set to null?
And the property "ValueIndex" set to -1?

My Chart has many Series, how can I know which Series label is tChart asking for?
And which data item's label is it refering to since "ValueIndex" is -1 ?
The GetAxisLabel Event is triggered for each Axis Label painted. There are two different uses for GetAxisLabel:
1) : Axis Labels are Values. Is this case, the Series parameter will be nil, and the ValueIndex will be -1.
2) : Axis Labels are Series points. The Series parameter will be a valid Series, and the ValueIndex will be the current Series point position. You can change the LabelText referred parameter for drawing a different Axis Label.
If you want more information, I recommend you take a look in the TeeChart References documentation.
So this conclude that we cannot use Label.Add() to set the Label of a Series. Correct ?
As I explain in previous message your Memory Usage increase because you use AddLabels(). In it you are adding and removing labels of your series for each tick of Timer and it increments your memory usage. One way to reduce it is, modifying only the axis labels using for example, GetAxisLabel Event and adding the labels of series only once, so your results would be the same. Please, can you check if my previous recommendation with absolute and relative values works as you expect? If it doesn't works as you expect, please let me know and explain exactly what you have modified of your code.

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

jdsu
Newbie
Newbie
Posts: 22
Joined: Tue Jun 14, 2011 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by jdsu » Sat Apr 07, 2012 3:54 pm

Hi Sandra,

Using your code together with the GetAxisLabel event, there was no memory leak.
However, I'm unable to access the e.Series and e.ValueIndex.

Upon your advise, I look up the Help on GetAxisLabel event and it says that if the Labels.Style is AxisLabelStyle.Text, Series & ValueIndex will be valid.

So I added this line to my code :
tChart1.Axes.Bottom.Labels.Style = AxisLabelStyle.Text;

And for the GetAxisLabel event, I changed it to make use of e.Series and e.ValueIndex
private void tChart1_GetAxisLabel(object sender, GetAxisLabelEventArgs e)
{
if (sender == tChart1.Axes.Bottom)
{
DateTime firstValue = e.Series.XValues.AsDateTime(0);
DateTime itemValue = e.Series.XValues.AsDateTime(e.ValueIndex);
e.LabelText = itemValue.Subtract(firstValue).ToString();
}
}

To my surprise, the memory leak problem came back.
Can you advise what is the correct way in order to use the e.Series and e.ValueIndex?

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Memory Usage keep increasing when auto scrolling chart

Post by Sandra » Tue Apr 10, 2012 3:04 pm

Hello jdsu,

Ok. I suggest you don't use Series and ValueIndex and instead of these I recommend you use next code :

Code: Select all

     void tChart1_GetAxisLabel(object sender, GetAxisLabelEventArgs e)
        {
            if (sender == tChart1.Axes.Bottom)
            {
             
                DateTime firstValue = DateTime.FromOADate(tChart1[0].XValues[0]);
                DateTime itemValue = DateTime.Parse(e.LabelText);
                e.LabelText = itemValue.Subtract(firstValue).ToString();

            }
        }
I have check it and works fine for me, the idea is use e.LabelText to achieve the correct value label axis. Can you tell us if previous code works as you expect?

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Post Reply