Visifire Forums: Silverlight Managed Code Charting Memory Usage - Visifire Forums

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

Silverlight Managed Code Charting Memory Usage Memory usage growing when using charts created in managed code

#1 User is offline   filbert Icon

  • Newbie
  • Pip
  • Group: Members
  • Posts: 2
  • Joined: 27-July 10

Posted 27 July 2010 - 01:47 PM

Hi, I am trying to use Visifire charts to create a Silverlight based web display which will be running in IE8 24/7. This will be displaying RSS content and other data received from a WCF service in various charts.

I am using c# code to create the charts and there is only 1 chart on display at a time. The data is updated at various intervals so I am re-creating the chart code side and then updating the layout root. This is achieved by a DispatcherTimer event which fires every 30 seconds. I am noticing that the memory consumption of the application runs away and although periodically some of the allocated memory is recoverd, it will eventually run away into 100's MB's when left without an IE page refresh.

I have tried a simple project to test and I am having the same issues so I believe this is related to the visifire chart component. Please could you tell me if I am making errors in disposal of the chart as I seem to have encountered a memory leak. I have attached the xaml and cs I have used in a sample project which calls GC.Collect() for debug puposes but memory slowly creeps up and never returns to any base level. Any pointers to either my error, or bug in visifire would be much appreciated.

I am re-creating the chart as I want to retain the animation which occurs on chart load. I have tried calling .Clear() on titles, data series, legends and axes, setting them and the chart to null all of which still seems to leave something behind.

I have tried using visifire 3.1.3 and 3.1.4 Beta 2

Attached File  Mainpage.zip (1.28K)
Number of downloads: 5

Thanks in advance.
0

#2 User is offline   vivek Icon

  • Advanced Member
  • PipPipPip
  • Group: Team Visifire
  • Posts: 2,539
  • Joined: 19-March 08
  • Gender:Male
  • Location:Bangalore

Posted 28 July 2010 - 09:24 AM

Hi Filbert,

We will look into the memory leak issue and get back to you.
Regards,
Vivek
Team Visifire
0

#3 User is offline   filbert Icon

  • Newbie
  • Pip
  • Group: Members
  • Posts: 2
  • Joined: 27-July 10

Posted 31 July 2010 - 05:01 PM

View Postvivek, on 28 July 2010 - 10:24 AM, said:

Hi Filbert,

We will look into the memory leak issue and get back to you.

Hi Guys,

Any luck with this yet? Is this just something I'm not doing right?

Thanks,

Filbert.
0

#4 User is offline   vivek Icon

  • Advanced Member
  • PipPipPip
  • Group: Team Visifire
  • Posts: 2,539
  • Joined: 19-March 08
  • Gender:Male
  • Location:Bangalore

Posted 02 August 2010 - 04:48 AM

Hi Filbert,

Yes we found that there is some leak while removing and re-creating the chart at realtime. It is happening with Silverlight only. Still we are investigating on this issue. We will update you on the status periodically.
Regards,
Vivek
Team Visifire
0

#5 User is offline   wint100 Icon

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 96
  • Joined: 29-June 09

Posted 01 September 2010 - 08:45 AM

Hi,

I am also seeing a memory leak in Silverlight 4, is this issue fixed yet? It seems a lot worse when using databinding.
It's better to understand a little, than to misunderstand a lot.
0

#6 User is offline   vivek Icon

  • Advanced Member
  • PipPipPip
  • Group: Team Visifire
  • Posts: 2,539
  • Joined: 19-March 08
  • Gender:Male
  • Location:Bangalore

Posted 01 September 2010 - 08:47 AM

Hi wint,

Yes there is still some leak exists in Silverlight 4 also. This happens while removing and re-creating a chart control each time inside a timer.
Regards,
Vivek
Team Visifire
0

#7 User is offline   wint100 Icon

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 96
  • Joined: 29-June 09

Posted 01 September 2010 - 12:32 PM

]When is this due to be fixed?I've tried leaving the Chart object alive, instead of nulling out the Chart, but after the first run, it flags nullException 'Oject Reference not set to an Instance .....' on this section, even though debugging shows 96 datapoints exist, and 2 series exist, and Index=0:

Chart1.Series[0].DataPoints[index].YValue = c._OnHoursTotal; // Changing the dataPoint YValue at runtime
Chart1.Series[1].DataPoints[index].YValue = c._OffHoursTotal; // Changing the dataPoint YValue at runtime

public void DailyElecDataSeries()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Chart1Grid.Children.Clear();
            //Chart1 = new Chart();
            if (Chart1.Series.Count > 0)
            {
                Chart1.Series[0].DataPoints.Clear();
                if (Chart1.Series.Count>1)Chart1.Series[1].DataPoints.Clear();
                Chart1.Series.Clear();
            }
            Chart1.Width = 400;
            Chart1.Height = 200;
            Chart1.ScrollingEnabled = false;
            Chart1.ShadowEnabled = true;
            // Chart1.ColorSet = "VisiOrange";
            Chart1.View3D = true;
            Chart1.LightingEnabled = true;
            Chart1.Background = new SolidColorBrush(Colors.Gray);
            Chart1Day = new Title();
            Chart1PrevDay = new Title();
            Chart1AxisY = new Axis();
            //Chart1.Rendered += new EventHandler(Chart1_Rendered);
            Chart1.BorderBrush = new SolidColorBrush(Colors.Black);
            Chart1.Series.Add(new DataSeries() { RenderAs = RenderAs.StackedColumn });
            Chart1.Series.Add(new DataSeries() { RenderAs = RenderAs.StackedColumn });
            Chart1.AnimatedUpdate = true;
            Chart1.AnimationEnabled = true;
            sDate = DateTime.Now.ToShortDateString();
            sDate2 = DateTime.Now.AddDays(-1).ToShortDateString();
            CO2Multiplier = ObjRefs[CurrentBuilding].ElecCO2;
            CarbonMultiplier = ObjRefs[CurrentBuilding].ElecCarbon;
            Chart1.Titles.Clear();
            Chart1.AxesY.Clear();
            //Chart1.AxesX.Clear();


            try
            {
                decimal consumption = 0;
                foreach (var c in ElecDayData)
                {
                    decimal dec;
                    if (Decimal.TryParse(c._day_data.ToString(), out dec))
                    {
                        consumption += dec;


                    }
                }

                Value1 = Decimal.Round(consumption, 0).ToString() + " kWh";
                Value2 = (Decimal.Round(consumption * Convert.ToDecimal(CO2Multiplier), 0).ToString()) + " kg";
                //Value3 = (Decimal.Round((Convert.ToInt32((ElecDayData.Compute("sum(day_data)*" + CarbonMultiplier + "", "")))), 2).ToString()) + " kg";
                TodayCO2 = Convert.ToDouble(Decimal.Round(consumption * Convert.ToDecimal(CO2Multiplier), 2).ToString());

                consumption = 0;
                foreach (var c in ElecPrevDayData)
                {
                    decimal dec;
                    if (Decimal.TryParse(c._day_data.ToString(), out dec))
                    {
                        consumption += dec;

                    }
                }

                Value3 = Decimal.Round(consumption, 0).ToString() + " kWh";
                Value4 = (Decimal.Round(consumption * Convert.ToDecimal(CO2Multiplier), 0).ToString()) + " kg";
                //Value6 = (Decimal.Round((Convert.ToInt32((ElecPrevDayData.Compute("sum(day_data)*" + CarbonMultiplier + "", "")))), 2).ToString()) + " kg";

                //Chart1AxisY.AxisMaximum = (Math.Max(Convert.ToDecimal(ElecDayData.Max(p => p._day_data.ToString())), Convert.ToDecimal(ElecPrevDayData.Max(p => p._day_data.ToString()) + 1).ToString());
                //Also add in the Axis Title at this point,X Axis Title is added in another Method
                Chart1AxisY.Title = "kWh";
                Chart1.AxesY.Add(Chart1AxisY);
                //Chart1.AxesX.Add(Dayaxis);


                //Create Chart Titles
                Chart1Day.Text = "Electricity Usage Today";


                Chart1PrevDay.Text = "Electricity Usage Yesterday";

                // Set DataSeries property

                Chart1.Series[0].LegendText = "On Hours (kWh)";
                Chart1.Series[1].LegendText = "Off Hours (kWh)";

                
                

                foreach (var c in ElecDayData)
                {

                    dataPoint = new DataPoint();
                    dataPoint.AxisXLabel = Convert.ToDateTime(c._Date).ToString("HH:mm");

                   //  Add dataPoint to DataPoints collection
                    Chart1.Series[0].DataPoints.Add(dataPoint);
                    dataPoint = null;

                    dataPoint = new DataPoint();
                    dataPoint.AxisXLabel = Convert.ToDateTime(c._Date).ToString("HH:mm");

                    //  Add dataPoint to DataPoints collection
                    Chart1.Series[1].DataPoints.Add(dataPoint);
                    dataPoint = null;

                }
                

                if (count == 0)
                {
                    
                    Chart1.Titles.Add(Chart1Day);
                    int index = 0;
                    foreach (var c in ElecDayData)
                    {
                        // Update YValue property of the DataPoint
                        Chart1.Series[0].DataPoints[index].YValue = c._OnHoursTotal; // Changing the dataPoint YValue at runtime
                        Chart1.Series[1].DataPoints[index].YValue = c._OffHoursTotal; // Changing the dataPoint YValue at runtime

                        index++;
                    }
                }
                else
                {
                    
                    Chart1.Titles.Add(Chart1PrevDay);
                    int index = 0;
                    foreach (var c in ElecPrevDayData)
                    {
                        // Update YValue property of the DataPoint
                        Chart1.Series[0].DataPoints[index].YValue = c._OnHoursTotal; // Changing the dataPoint YValue at runtime
                        Chart1.Series[1].DataPoints[index].YValue = c._OffHoursTotal; // Changing the dataPoint YValue at runtime

                        index++;
                    }
                }



            }


            catch (Exception ex)
            {
                string msg = "Daily Electricity Chart Series Rendering Error: ";
                msg += ex.InnerException.ToString();
                throw new Exception(msg);

            }
            finally
            {
                Chart1Grid.Children.Add(Chart1);
                
                //Chart1 = null;
                Chart1Day=null;
                Chart1PrevDay = null;
                Chart1AxisY = null;




            }
        }

It's better to understand a little, than to misunderstand a lot.
0

#8 User is offline   vivek Icon

  • Advanced Member
  • PipPipPip
  • Group: Team Visifire
  • Posts: 2,539
  • Joined: 19-March 08
  • Gender:Male
  • Location:Bangalore

Posted 01 September 2010 - 01:00 PM

Wint,

Can you please tell me which version of Visifire are you using?
Regards,
Vivek
Team Visifire
0

#9 User is offline   wint100 Icon

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 96
  • Joined: 29-June 09

Posted 01 September 2010 - 01:31 PM

I'm using 3.5.8GA
It's better to understand a little, than to misunderstand a lot.
0

#10 User is online   shoaib Icon

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 106
  • Joined: 20-May 10
  • Gender:Male
  • Location:Bangalore

Posted 02 September 2010 - 06:57 AM

Hi,

Can you please tell me why are you creating chart each time? Instead of that you can just update DataSeries and DataPoints at real-time.


Regards,
Shoaib
0

#11 User is offline   wint100 Icon

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 96
  • Joined: 29-June 09

Posted 02 September 2010 - 07:15 AM

Hi,

This has been converted from a WPF app to Silverlight. In the WPF app, I had to null each chart and create new on each tick, otherwise there was a huge memory leak.

As mentioned though, the code I supplied above, is not creating a new chart each time, as this part is commented out. The code throws an exception though as mentioned, even though 96 datapoints, and 2 series exist.

Is there a scheduled release date for the Silverlight memory leak fix, as this is eating up 5MB each time. Line charts seem to be the worst affected, and if I use databinding, it goes up even more.

Is there a recommened method to reduce memory leaks, as it seems to be a big issue with 24/7 dashboard style apps. My app ran up to 1GB memory usage over night!?

Cheers
It's better to understand a little, than to misunderstand a lot.
0

#12 User is offline   vivek Icon

  • Advanced Member
  • PipPipPip
  • Group: Team Visifire
  • Posts: 2,539
  • Joined: 19-March 08
  • Gender:Male
  • Location:Bangalore

Posted 02 September 2010 - 09:47 AM

Hi wint,

Can you please tell me why are you clearing and adding chart inside Chart1Grid every time. Instead of this you just have to create the chart only once and update the DataSeries and DataPoints in each pass.

Example:

In the code below, I am just clearing and adding DataPoints inside each DataSeries. Even you need not have to clear the DataSeries, Title and Axis each time.

public void DailyElecDataSeries()
        {
            if (Chart1.Series.Count > 0)
            {
                Chart1.Series[0].DataPoints.Clear();
                if (Chart1.Series.Count > 1)
                    Chart1.Series[1].DataPoints.Clear();
            }

            try
            {
                decimal consumption = 0;
                foreach (var c in ElecDayData)
                {
                    decimal dec;
                    if (Decimal.TryParse(c._day_data.ToString(), out dec))
                    {
                        consumption += dec;
                    }
                }

                Value1 = Decimal.Round(consumption, 0).ToString() + " kWh";
                Value2 = (Decimal.Round(consumption * Convert.ToDecimal(CO2Multiplier), 0).ToString()) + " kg";
                //Value3 = (Decimal.Round((Convert.ToInt32((ElecDayData.Compute("sum(day_data)*" + CarbonMultiplier + "", "")))), 2).ToString()) + " kg";
                TodayCO2 = Convert.ToDouble(Decimal.Round(consumption * Convert.ToDecimal(CO2Multiplier), 2).ToString());

                consumption = 0;
                foreach (var c in ElecPrevDayData)
                {
                    decimal dec;
                    if (Decimal.TryParse(c._day_data.ToString(), out dec))
                    {
                        consumption += dec;

                    }
                }

                Value3 = Decimal.Round(consumption, 0).ToString() + " kWh";
                Value4 = (Decimal.Round(consumption * Convert.ToDecimal(CO2Multiplier), 0).ToString()) + " kg";
                //Value6 = (Decimal.Round((Convert.ToInt32((ElecPrevDayData.Compute("sum(day_data)*" + CarbonMultiplier + "", "")))), 2).ToString()) + " kg";

                foreach (var c in ElecDayData)
                {
                    dataPoint = new DataPoint();
                    dataPoint.AxisXLabel = Convert.ToDateTime(c._Date).ToString("HH:mm");

                    //  Add dataPoint to DataPoints collection
                    Chart1.Series[0].DataPoints.Add(dataPoint);
                    dataPoint = null;

                    dataPoint = new DataPoint();
                    dataPoint.AxisXLabel = Convert.ToDateTime(c._Date).ToString("HH:mm");

                    //  Add dataPoint to DataPoints collection
                    Chart1.Series[1].DataPoints.Add(dataPoint);
                    dataPoint = null;
                }

                if (count == 0)
                {

                    int index = 0;
                    foreach (var c in ElecDayData)
                    {
                        // Update YValue property of the DataPoint
                        Chart1.Series[0].DataPoints[index].YValue = c._OnHoursTotal; // Changing the dataPoint YValue at runtime
                        Chart1.Series[1].DataPoints[index].YValue = c._OffHoursTotal; // Changing the dataPoint YValue at runtime

                        index++;
                    }
                }
                else
                {
                    int index = 0;
                    foreach (var c in ElecPrevDayData)
                    {
                        // Update YValue property of the DataPoint
                        Chart1.Series[0].DataPoints[index].YValue = c._OnHoursTotal; // Changing the dataPoint YValue at runtime
                        Chart1.Series[1].DataPoints[index].YValue = c._OffHoursTotal; // Changing the dataPoint YValue at runtime

                        index++;
                    }
                }

            }
            catch (Exception ex)
            {
                string msg = "Daily Electricity Chart Series Rendering Error: ";
                msg += ex.InnerException.ToString();
                throw new Exception(msg);

            }
        }

Regards,
Vivek
Team Visifire
0

#13 User is offline   wint100 Icon

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 96
  • Joined: 29-June 09

Posted 02 September 2010 - 10:12 AM

Hi,

I WAS nulling the chart to clear it from memory, as leaving the chart in memory and only clearing datapoints and series was leaking memory in WPF application.

Also, I was getting Object reference not set to an instance of an object when only clearing datapoitns an series, even though series and datapoints exist.

Is your silverlight memory leak fixed yet?
It's better to understand a little, than to misunderstand a lot.
0

#14 User is offline   vivek Icon

  • Advanced Member
  • PipPipPip
  • Group: Team Visifire
  • Posts: 2,539
  • Joined: 19-March 08
  • Gender:Male
  • Location:Bangalore

Posted 02 September 2010 - 10:58 AM

Hi wint,

There is already some memory leak exists natively in Silverlight. I would suggest you to update the code as shown below:

foreach (var c in ElecDayData)
{
        dataPoint = new DataPoint();
        dataPoint.AxisXLabel = Convert.ToDateTime(c._Date).ToString("HH:mm");

        // Update YValue property of the DataPoint
        dataPoint.YValue = c._OnHoursTotal;

        //  Add dataPoint to DataPoints collection
        Chart1.Series[0].DataPoints.Add(dataPoint);
  
       dataPoint = null;

       dataPoint = new DataPoint();
       dataPoint.AxisXLabel = Convert.ToDateTime(c._Date).ToString("HH:mm");

       // Update YValue property of the DataPoint
       dataPoint.YValue = c._OffHoursTotal;

       //  Add dataPoint to DataPoints collection
       Chart1.Series[1].DataPoints.Add(dataPoint);
       dataPoint = null;
}


In the above code I am setting YValue property before adding the DataPoint inside the DataSeries. Hope this will help.
Regards,
Vivek
Team Visifire
0

#15 User is offline   wint100 Icon

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 96
  • Joined: 29-June 09

Posted 02 September 2010 - 09:28 PM

Hi,

I've now modified my code to suit all of your suggestions. I know there was a leak in SL4, that was fixed and a service update was released yesterday. There is link on Tim Heuer's blogsite about this memory leak:

http://timheuer.com/blog/


I'm still seeing leaks with this fix, and the modified code. I'll see how it is in the morning, after a night running and post back with results.
It's better to understand a little, than to misunderstand a lot.
0

#16 User is offline   wint100 Icon

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 96
  • Joined: 29-June 09

Posted 03 September 2010 - 05:06 AM

Hi,

The memoru usage has gone up to 600MB over night. I'm using ANTS Memory profiler 6 to search for leaks. It looks as though the heap size is not growing more than 0.5MB, as ANTS doesn't showing hardly any increase in memory. It is the private bytes that is increasing. SO looks like the GC is clearing up. I've also setup a log writing the GC.TotalMemory, and this isn't increasing either.

So, it looks like the private bytes is increasing, the the GC heap. Not sure what this means yet. Will do some research.
It's better to understand a little, than to misunderstand a lot.
0

#17 User is offline   vivek Icon

  • Advanced Member
  • PipPipPip
  • Group: Team Visifire
  • Posts: 2,539
  • Joined: 19-March 08
  • Gender:Male
  • Location:Bangalore

Posted 03 September 2010 - 05:42 AM

Hi Wint,

Even we did not find any leaks using the above code. Please let us know what exactly you found as you said memory usage is going up to 600 MB but ANTS memory profiler is not showing any increase in memory.
Regards,
Vivek
Team Visifire
0

#18 User is offline   wint100 Icon

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 96
  • Joined: 29-June 09

Posted 03 September 2010 - 06:09 AM

Hi,

The private bytes in task manager has increased to 600MB. The heap size in ANTS has not increased.

Also, using the new code, the datapoints are no longer animated on update, they just appear without any animation. Although I am still removing the series on each Tick, as the chart can either be line or column for different number of series each tick.
It's better to understand a little, than to misunderstand a lot.
0

#19 User is offline   vivek Icon

  • Advanced Member
  • PipPipPip
  • Group: Team Visifire
  • Posts: 2,539
  • Joined: 19-March 08
  • Gender:Male
  • Location:Bangalore

Posted 03 September 2010 - 06:29 AM

Hi Wint,

Can you please tell me whether the count of DataPoints is changing while updating DataPoints at real-time Or the number of DataPoints will be same in each pass?
Regards,
Vivek
Team Visifire
0

#20 User is offline   wint100 Icon

  • Advanced Member
  • PipPipPip
  • Group: Members
  • Posts: 96
  • Joined: 29-June 09

Posted 03 September 2010 - 06:35 AM

datapoints should be staying the same. 96 on each pass.

Does this make a difference?
It's better to understand a little, than to misunderstand a lot.
0

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users