Need help understanding how to use the profiler.

Use this forum for questions on how to use .NET Memory Profiler and how to analyse memory usage.
Post Reply
SamSamson
Posts: 2
Joined: Thu Oct 18, 2007 2:15 am

Need help understanding how to use the profiler.

Post by SamSamson » Mon Oct 22, 2007 4:04 am

Greetings.

I've recently purchased MemProfiler 3.0 but even after completing the tutorial I a having difficulty identifying and finding leaks in my aplication.

The App has been built over the last 2 years so its fairly larger and uses a few 3rd party .net controls.

I've got my head (I think around the real-time view and comparing snapshots) however I am unsure what I am looking for.

In the real time I let the app run and watch the Total instances and live instances. I leave it in a state that should have flat memory usage.

Take 1 snapshot .. wait some time then take the second and so on.

In the types view filtered by 'new or removed instances' I have some 150-200 entries ... nearly all system.xxx .. 1 or 2 I recognise as something I've coded. below is an example:

System.Drawing.Drawing2D GraphicsPath 1877 1447 1459 -12 0 0 0 0 570508 115478
(sorry that didn't paste well)

nearly all the instances have 1000's of undisposed instances (total) the help file says ideally these should be 0 .. so are these all leaks?

Next when I click on an instance I go to the type details path .. I get a call stack trace like such:

GraphicsPath.Clone()
if..ctor(IHitTestTarget, IColorable, g4, hv, fv)
if..ctor(IHitTestTarget, IColorable, g4, hv)
if..ctor(IHitTestTarget, IColorable, g4)
i.a.b(char)
DigitalAppearance.rootNode_Update(object, jk)
bc.a(jk)
h5.a(bc, gj)
h5.a(am, gj, cc)
cc.a(am, ap)
cc.a(am, ap)
cc.a(am, ap)
cc.a(am, ap)
cc.a(am, ap)
cc.a(am, ap)
cc.a(am, ap)
cc.a(am, ap)
cc.a(am, ap)
cc.a(am, ap)
cc.a(am, ap)
cc.a(am)
cc.a(br)
br.b(IGraphicsEx)
BaseGauge.a(IGraphicsEx, RectangleF)
BaseGauge.OnPaint(PaintEventArgs)
Control.PaintWithErrorHandling(PaintEventArgs, short, bool)
Control.WmPaint(Message&)
Control.WndProc(Message&)
Control.ControlNativeWindow.OnMessage(Message&)
Control.ControlNativeWindow.WndProc(Message&)
NativeWindow.Callback(IntPtr, int, IntPtr, IntPtr)
[Unmanaged to managed transition]
[Managed to unmanaged transition]
UnsafeNativeMethods.DispatchMessageW(NativeMethods.MSG&)
Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int, int, int)
Application.ThreadContext.RunMessageLoopInner(int, ApplicationContext)
Application.ThreadContext.RunMessageLoop(int, ApplicationContext)
Application.Run(Form)
Program.Main()

Now Program.Main() is the only thing I can click on. There is a mention of BaseGauge which is probably a reference to a 3rd party .net gauge control .. but there are quite a lot of gauges used in this application .. and of cause they are ALL below Program.Main .. how do I narrow down the search to find exactly where in the code this instance is getting created each time.

so in summary what do I look for to identify a leak, and how do I drill down to find it in my code.

I hope my ramblings make some sense and you can guide me a little on how to use this tool.

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

Post by Andreas Suurkuusk » Mon Oct 22, 2007 6:33 pm

You have 1447 new and 1459 removed instances of the GraphicsPath class. A lot of instances have been replaced between the snapshot, but the total number of instances does not increase, so there is no indication of a managed memory leak.

However, you do have a substantial amount of undisposed instances of the GraphicsPath. A GraphicsPath wraps an unmanaged GDI+ resource, which could potentially consume a significant amount of unmanaged memory. The managed data of the GraphicsPath only occupies 4 bytes (or 8 bytes on 64-bit OS), so the managed memory pressure will be very low for the GraphicsPath instances (and any other GDI+ instances). The GraphicsPaths are released by the finalizer, but since the managed memory pressure is low it might take a while for a GC to kick in.

The recommendation is of course to make sure that the GraphicsPath instances are correctly disposed. Unfortunately this is not something that you will be able to correct yourself, since the GraphicsPaths are created by your 3rd part gauge library (the allocation stack shows that the GraphicsPath is created in the OnPaint event of BaseGauge, via a lot of obfuscated methods).

If you believe that this causes a problem with your application, you might want to mention this to the makers of the Gauge control.
Best regards,

Andreas Suurkuusk
SciTech Software AB

SamSamson
Posts: 2
Joined: Thu Oct 18, 2007 2:15 am

Post by SamSamson » Wed Oct 24, 2007 1:50 am

Ta ... that made me look in the right direction ... it was the 3rd party gauges .. and they are looking into it.

tnx.

Post Reply

Who is online

Users browsing this forum: No registered users and 15 guests