This is a migrated thread and some comments may be shown as answers.

Is this memory leak?

3 Answers 102 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
King Chan
Top achievements
Rank 1
King Chan asked on 13 Sep 2010, 06:23 PM

Dear Telerik Staff,

I wonder if I did the garbage collection incorrectly, or this is memory leak?
I spent few days to research about Silverlight's memory leak issues and I know it affected Telerik's controls as well, I just want to see if this is caused by same reason or it is just the way I do the garbage collection was wrong.


The demo I created is very simple, Button "Create Obj" will create 10 RadScheduler and add into LayoutRoot and to a List<RadScheduler>.

Then the Button "Collects" will run though the List<RadSchdeduler> to remove each RadScheduler from LayoutRoot, then set each RadScheduler object to null, Clear() the list, then do the: 

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect(); 


1) Before Click Create Obj Button:
Task Manager:
IExplorer.exe
Memory(Private Working Set): 42,828k
Performance Memory: 656MB

2) After Click Create Obj Button:
Task Manager:
IExplorer.exe
Memory(Private Working Set): 194,828k
Performance Memory: 805MB

3) After Click "Collect" Button:
Task Manager:
IExplorer.exe
Memory(Private Working Set): 194,280k
Performance Memory: 801MB

For same scenario, if I create Button obj(500 Buttons) instead of RadScheduler, I can see the memory increased few MB and released few MB properly.
But again, for same scenario, if I create RadDialog(10 RadDialog with no Content) obj this time instead of RadScheduler, then I close it, null it, GC.Collect it, it will release PART OF the memory, and have around 1 MB didn't release.

And here is the demo code (everything created in MainPage.xaml.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Telerik.Windows.Controls;
using System.Reflection.Emit;
using System.Diagnostics;
  
namespace RadControlsSilverlightApp4
{
    public partial class MainPage : UserControl
    {
        TextBlock aLabel = new TextBlock();
  
        List<RadScheduler> SchedulerList = new List<RadScheduler>();
        public MainPage()
        {
            InitializeComponent();
            this.LayoutRoot.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(100, GridUnitType.Auto) });
            this.LayoutRoot.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(100, GridUnitType.Pixel) });
            this.LayoutRoot.RowDefinitions.Add(new RowDefinition { Height = new GridLength(100, GridUnitType.Auto) });
            this.LayoutRoot.RowDefinitions.Add(new RowDefinition { Height = new GridLength(70, GridUnitType.Auto) });
            this.LayoutRoot.RowDefinitions.Add(new RowDefinition { Height = new GridLength(70, GridUnitType.Auto) });
            this.LayoutRoot.RowDefinitions.Add(new RowDefinition { Height = new GridLength(500, GridUnitType.Auto) });
  
            Button aButton = new Button();
            aButton.Content = "Create Objs";
            aButton.SetValue(Grid.RowProperty, 0);
            aButton.SetValue(Grid.ColumnProperty, 0);
            this.LayoutRoot.Children.Add(aButton);
    
            Button aCollectButton = new Button();
            aCollectButton.Content = "Collects";
            aCollectButton.SetValue(Grid.RowProperty, 1);
            aCollectButton.SetValue(Grid.ColumnProperty, 0);
            this.LayoutRoot.Children.Add(aCollectButton);
  
            aLabel.SetValue(Grid.RowProperty, 1);
            aLabel.SetValue(Grid.ColumnProperty, 1);
            aLabel.Text = GC.GetTotalMemory(true).ToString();
            this.LayoutRoot.Children.Add(aLabel);
  
            Button aUpdateButton = new Button();
            aUpdateButton.Content = "Update";
            aUpdateButton.SetValue(Grid.RowProperty, 2);
            aUpdateButton.SetValue(Grid.ColumnProperty, 0);
            this.LayoutRoot.Children.Add(aUpdateButton);
  
            aButton.Click +=new RoutedEventHandler(aButton_Click);
            aCollectButton.Click +=new RoutedEventHandler(aCollectButton_Click);
            aUpdateButton.Click += new RoutedEventHandler(aUpdateButton_Click);
  
        }
  
        public void aButton_Click (object sender, RoutedEventArgs e){
            Debug.WriteLine("Create 10 Obj");
               
            for (int i = 0; i < 10; i++)
              
                RadScheduler aScheduler = new RadScheduler();
                aScheduler.SetValue(Grid.RowProperty, 3);
                aScheduler.SetValue(Grid.ColumnProperty, 1);
                SchedulerList.Add(aScheduler);
                this.LayoutRoot.Children.Add(aScheduler);
                 
            }
  
            aLabel.Text = GC.GetTotalMemory(false).ToString(); 
            Debug.WriteLine("Obj Count: " + SchedulerList.Count.ToString());
            Debug.WriteLine("Obj Count: " + this.LayoutRoot.Children.Count.ToString());
        }
  
        public void aCollectButton_Click(object sender, RoutedEventArgs e)
        
  
            for (int i = 0; i < SchedulerList.Count; i++)
            {
                this.LayoutRoot.Children.Remove(SchedulerList[i]);
                SchedulerList[i].DataContext = null;                
                SchedulerList[i] = null;
            }
            SchedulerList.Clear();
  
            Debug.WriteLine("Collect!");
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            Debug.WriteLine("Collected!");
            Debug.WriteLine("Obj Count: " + SchedulerList.Count.ToString());
            Debug.WriteLine("Obj Count: " + this.LayoutRoot.Children.Count.ToString());
            aLabel.Text = GC.GetTotalMemory(false).ToString();
        }
  
  
        public void aUpdateButton_Click(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("Update!");
            Debug.WriteLine("Obj Count: " + this.LayoutRoot.Children.Count.ToString());
            aLabel.Text = GC.GetTotalMemory(false).ToString();
  
        }
    }
}
=========
Update: I just used WeakReference to check, I realize none of the RadScheduler get collected, they are all Alive.
And for the RadDialog, I can see few of the RadDialog object is Alive, and others was got collected, it happens if I try keep clicking Create and Collect frequently. (i.e Created like 500 RadDialog on screen, after collects, there is 3 alives)
=========
Thanks for your help,
King


3 Answers, 1 is accepted

Sort by
0
Accepted
Hristo
Telerik team
answered on 14 Sep 2010, 07:50 AM
Hello King Chan,

Unfortunately Silverlight 4 GDR1 did not fix all memory leaks. We are in a process of preparing Q2 Service Pack 2 (which workarounds known framework leaks and also fix few memory leaks caused by our code).
It will be official in a week or two.

Let us know if you need more information.

Greetings,
Hristo
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
King Chan
Top achievements
Rank 1
answered on 14 Sep 2010, 01:59 PM
Thanks for your reply, I guess that's mean I didn't did wrong on collecting?
I am still new to silverlight, just want to make sure.
0
Hristo
Telerik team
answered on 15 Sep 2010, 07:55 AM
Hi King Chan,

When testing for memory leaks I don't observe Task Manager (working set). Garbage collection is not something that can be controlled. The correct approach is to create WeakReferences.

I hope that this will help you.

All the best,
Hristo
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
General Discussions
Asked by
King Chan
Top achievements
Rank 1
Answers by
Hristo
Telerik team
King Chan
Top achievements
Rank 1
Share this question
or