Luis Guerrero EN

Detecting memory issues with Silverlight

by on Apr.30, 2010, under Debugging, Silverlight

Hi all!

Today we’re going to talking about a memory leak issue found in Silverlight 4 and report on Silverlight’s forum by tsheflin As you know Silverlight is a .NET technology, so it’s mean you can use C# or Visual Basic to build your Silverlight’s applications and you have all the goodness of .NET, automatic memory management, garbage collector, type safety and so on.

But sometimes something goes wrong and we found that there are memory leaks on a dot net application; Silverlight is not free about this issues. So we’re going to identify how to find this memory issues with WinDBG and sos for Silverlight.

I’m going to use the same example provided by the user of the forum. You can download from here.

First of all we need to build and run our application in release mode, this is important because there are a few differences between debug and release mode, then run the application without debugging and now its WinDBG time!

If your browser is Windows Internet Explorer 8 and you running Windows 7 or Vista, you may know that IE runs each tab in a separate process so you need to identify first witch process is running your code, in my example I found my process is 7958.

With WinDBG open (you can download from here, go to File -> Attach to process (F6), and select your process id (in my machine is 7958), immediately appear output window with all the basic debug information. Since our application is a managed application and WinDBG is designed to debug native application we need a debugger extension to debug managed application. What we need is SOS (Son of Strike). SOS is located in my machine here C:\Program Files (x86)\Microsoft Silverlight\4.0.50401.0\sos.dll for every version of Silverlight there is a SOS version, so depending the Silverlight version you’re debugging you need to load this extension.

Once we have this file, SOS can be loaded writing

.load C:\Program Files (x86)\Microsoft Silverlight\4.0.50401.0\sos.dll

And now we have all the power of SOS in WinDBG.

Next we need to find a valid memory address for our type SilverlightVisualTreeRemovalFail.SilverlightControl1 so we’re going to use !dumpheap command to dump all heap types and filter by this type writing this:

!dumpheap -type SilverlightVisualTreeRemovalFail.SilverlightControl1

0:005> !dumpheap -type SilverlightVisualTreeRemovalFail.SilverlightControl1

Address MT Size

087aad6c 04a45230 92

087ab460 04a45230 92

087ab6f0 04a45230 92

087ac01c 04a45230 92

087ac710 04a45230 92

087ace04 04a45230 92

087ad4f8 04a45230 92

087adbec 04a45230 92

087ae2e0 04a45230 92

087ae9d4 04a45230 92

087af0c8 04a45230 92

087af7bc 04a45230 92

087afeb0 04a45230 92

087b05a4 04a45230 92

087b0c98 04a45230 92

087b138c 04a45230 92

087b1a80 04a45230 92

087b2174 04a45230 92

087b2868 04a45230 92

087b2f5c 04a45230 92

087b3650 04a45230 92

087b3d44 04a45230 92

087b4438 04a45230 92

087b4b2c 04a45230 92

087b5220 04a45230 92

087b5914 04a45230 92

087b6008 04a45230 92

087b66fc 04a45230 92

087b6df0 04a45230 92

087b74e4 04a45230 92

087b7bd8 04a45230 92

087b82cc 04a45230 92

087b89c0 04a45230 92

087b90b4 04a45230 92

087b97a8 04a45230 92

087b9e9c 04a45230 92

087ba590 04a45230 92

087bac84 04a45230 92

087bb378 04a45230 92

087bba6c 04a45230 92

087bc160 04a45230 92

087bc854 04a45230 92

087bcf48 04a45230 92

087bd63c 04a45230 92

087bdd30 04a45230 92

087be424 04a45230 92

087beb18 04a45230 92

087bf20c 04a45230 92

087bf900 04a45230 92

087bfff4 04a45230 92

In output window we found some addresses for this type, selecting one 087b1a80 we need to find witch object is referencing this object (this is what is causing not to be recoleted) writing this:

!gcroot 087b1a80
0:005> !gcroot 087b1a80

Note: Roots found on stacks may be false positives. Run "!help gcroot" for

more info.

Scan Thread 5 OSTHread 10e8

Scan Thread 22 OSTHread 1f8

Scan Thread 23 OSTHread 1588

DOMAIN(07134BE0):HANDLE(Pinned):4a912f8:Root: 09784260(System.Object[])->

08796c78(System.Collections.Generic.Dictionary`2[[System.IntPtr, mscorlib],[System.Object, mscorlib]])->

09788260(System.Collections.Generic.Dictionary`2+Entry[[System.IntPtr, mscorlib],[System.Object, mscorlib]][])->



We found that this object (087b1a80) is reference by other object and on the top of the list there is a HANDLE(Pinned):4a912f8 so its means that the garbage collection will always found a path to this object causing not to be garbage collected.

Now we identify the problem, but for now we can’t do anything because this is a Microsoft issue, because Microsoft’s code is referencing our control so we can’t fix this by ourselves. If this code is from us what we need to is simply remove references from this dictionary and then the control will be garbage collected.

We can also dump all the heap to a file and then open this file with CLRProfiler, type !traverseheap and file output and the open with CLRProfiler.

All the best.

Luis Guerrero.

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!