I am using Ant Memory Profiler 8 to profile a small test Silverlight 5 application. I waited for the main application to load and then add, remove and dispose a simple UserControl. I then took the first memory snapshot. I add, remove and dispose the same
simple UserControl several times in a loop. I then took the second memory snapshot. Looking at the class list the size of all of the objects was smaller after the second snapshot. Agcore increased 10KB and increased by 10-15KB every time I add and remove the
same control. How can I see what is causing agcore to increase? Why is the memory not freeing up?
MainPage.xaml
<UC:ViewBase x:Class="TestSilverlight.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:UC="clr-namespace:TestSilverlight"><StackPanel Background="DarkGray"><TextBox x:Name="TbLoopCount"></TextBox><Button x:Name="BtnLoop" Content="Loop" /><Button x:Name="BtnAddControls" Content="Add Controls" /><Button x:Name="BtnRemoveControls" Content="Remove Controls" /><StackPanel x:Name="LayoutRoot" ></StackPanel></StackPanel></UC:ViewBase>
MainPage.xaml.vb
Partial Public Class MainPage Inherits ViewBase Private _suc1 As SUC1 Public Sub New() InitializeComponent() AddControls() End Sub Private Sub AddControls() Handles BtnAddControls.Click _suc1 = New SUC1 LayoutRoot.Children.Add(_suc1) End Sub Private Sub RemoveControls() Handles BtnRemoveControls.Click LayoutRoot.Children.Remove(_suc1) _suc1.Dispose() End Sub Private Sub AddRemoveControls() Handles BtnLoop.Click Dim x As Double = Double.Parse(TbLoopCount.Text) For i = 0 To x RemoveControls() AddControls() Next End Sub End Class
ViewBase.vb
Public Class ViewBase Inherits UserControl Implements IDisposable #Region "IDisposable Support" Private disposedValue As Boolean ' To detect redundant calls ' IDisposable Protected Overridable Sub Dispose(disposing As Boolean) If Not Me.disposedValue Then If disposing Then Me.DataContext = Nothing End If End If Me.disposedValue = True End Sub ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources. Protected Overrides Sub Finalize() ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above. Dispose(False) MyBase.Finalize() End Sub ' This code added by Visual Basic to correctly implement the disposable pattern. Public Sub Dispose() Implements IDisposable.Dispose ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above. Dispose(True) GC.Collect() GC.SuppressFinalize(Me) End Sub #End Region End Class
SUC1.xaml
<UC:ViewBase x:Class="TestSilverlight.SUC1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:UC="clr-namespace:TestSilverlight"><Grid Name="LayoutRoot" Background="DarkGreen" Width="100" Height="100" /></UC:ViewBase>
SUC1.xaml.vb
Partial Public Class SUC1 Inherits ViewBase Public Sub New InitializeComponent() End Sub End Class
app.xaml
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="TestSilverlight.App"><Application.Resources></Application.Resources></Application>app.xaml.vb
Imports System.Diagnostics Imports System.Windows.Browser Partial Public Class App Inherits Application Public Sub New() InitializeComponent() End Sub Private Sub Application_Startup(ByVal o As Object, ByVal e As StartupEventArgs) Handles Me.Startup RootVisual = New MainPage() End Sub Private Sub Application_Exit(ByVal o As Object, ByVal e As EventArgs) Handles Me.Exit End Sub Private Sub Application_UnhandledException(ByVal sender As Object, ByVal e As ApplicationUnhandledExceptionEventArgs) Handles Me.UnhandledException ' If the app is running outside of the debugger then report the exception using ' the browser's exception mechanism. On IE this will display it a yellow alert ' icon in the status bar and Firefox will display a script error. If Not Debugger.IsAttached Then ' NOTE: This will allow the application to continue running after an exception has been thrown ' but not handled. ' For production applications this error handling should be replaced with something that will ' report the error to the website and stop the application. e.Handled = True Deployment.Current.Dispatcher.BeginInvoke(New Action(Of ApplicationUnhandledExceptionEventArgs)(AddressOf ReportErrorToDOM), e) End If End Sub Private Sub ReportErrorToDOM(ByVal e As ApplicationUnhandledExceptionEventArgs) Try Dim errorMsg As String = e.ExceptionObject.Message + e.ExceptionObject.StackTrace errorMsg = errorMsg.Replace(""""c, "'"c).Replace(ChrW(13) & ChrW(10), "\n") HtmlPage.Window.Eval("throw new Error(""Unhandled Error in Silverlight Application " + errorMsg + """);") Catch End Try End Sub End Class
Why be different when you can be yourself?