Help with profiler

Use this forum for questions on how to use .NET Memory Profiler and how to analyse memory usage.
Post Reply
drewpt
Posts: 2
Joined: Sat Sep 02, 2006 2:57 am

Help with profiler

Post by drewpt » Sat Sep 02, 2006 3:04 am

I've written a tiny test app to become familar with the profiler as well as get a better understanding of what I can and can't do in .NET.

I created a small user control with a button on it. I then placed this user control on a form in the designer.

I placed another button on the form and added a click handler to it.

In that click handler I do:

this.Controls.Remove(ctrl);
ctrl.Dispose();
ctrl = null;

When I run the profiler before and after the click I notice my user control is not released.

When I click on the user control instance I get this root path.

What is going on here? Other than the one click event on the button in Form1, I dont really do anything else.

System.Windows.Forms LayoutEventArgs #262
WindowsApplication1 Form1 #15
System.Windows.Forms Application.ThreadContext #2
System.Windows.Forms Application.ComponentManager System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int, int, int)

Andreas Suurkuusk
Posts: 1029
Joined: Wed Mar 02, 2005 7:53 pm

Post by Andreas Suurkuusk » Mon Sep 04, 2006 10:00 am

Hi,

I managed to reproduce your problem. As the rootpath you included shows, the UserControl is referenced by a LayoutEventArgs instance, which in turn is referenced by the Form1 instance. Investigating the fields of Form1 shows that the field cachedLayoutEventArgs references the LayoutEventArgs instance.

Code: Select all

LayoutventArgs cachedLayoutEventArgs	#262
And the allocation call stack of the LayoutEventArgs instance shows that it is created in PerformLayout.

Code: Select all

Control.System.Windows.Forms.Layout.IArrangedElement.PerformLayout(IArrangedElement, string)
LayoutTransaction.DoLayout(IArrangedElement, IArrangedElement, string)
Control.ControlCollection.Add(Control)
Form.ControlCollection.Add(Control)
Form1.InitializeComponent()
Form1..ctor()
Program.Main()
Using Reflector on this method indicates that the LayoutEventArgs instance is saved in the cachedLayoutEventArgs field when layout is suspended. This field is not cleared when the UserControl is removed or disposed, thus preventing the UserControl from beign GCed. Since the instance is only referenced by a single field, and not being added to a collection, this is not a serious memory leak. If you had two user controls and removed both of them, only one would be kept alive.

I did some further research and found out that the cachedLayoutEventArgs field is cleared when a new layout is performed, so adding a call to PerformLayout after removing the control will solve the problem.

Code: Select all

this.Controls.Remove(ctrl); 
ctrl.Dispose(); 
ctrl = null; 
this.PerformLayout();
Best regards,

Andreas Suurkuusk
SciTech Software AB

drewpt
Posts: 2
Joined: Sat Sep 02, 2006 2:57 am

Post by drewpt » Tue Sep 05, 2006 8:36 pm

Thank you very much. That helps me understand what I am seeing. I appreciate it. You have a fantastic tool.

Post Reply

Who is online

Users browsing this forum: Majestic-12 [Bot] and 22 guests