MANAGED DEBUGGING with WINDBG. Managed Heap. Part 3

Hi all,

This post is a continuation of MANAGED DEBUGGING with WINDBG. Managed Heap. Part 2.




·         We can take a look to which objects reference which objects in the heap:

We may see many objects in the heap that we think should have been cleaned up already. If they haven’t, it’s because they are still being referenced and GC can’t clean them.

We can look for references (“roots”) to an object. Let’s see this with a sample taken from an ASP.NET app:

0:000> !DumpHeap -stat


      MT    Count    TotalSize Class Name

0ee10034    19218      7149096 ASP.lab3_1_aspx

Total 1748273 objects

0:000> !DumpHeap -mt 0ee10034   


Heap 0

 Address       MT     Size


0556b268 0ee10034      372

0556ccac 0ee10034      372    

total 6524 objects


Heap 1

0:000> !GCRoot 0556b268

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

more info.

Scan Thread 15 OSTHread 2c4

Scan Thread 13 OSTHread c4c
















Scan Thread 22 OSTHread 830

Scan Thread 23 OSTHread f7c


If we take a look to the source code of Lab3_1.aspx page, we can see why the page is being kept in memory by the Cache object:

public partial class Lab3_1 : System.Web.UI.Page


    public void RemovedCallback(String k, Object v, System.Web.Caching.CacheItemRemovedReason r)


        //do stuff when the item is removed



    protected void Page_Load(object sender, EventArgs e)


        UserInfo u = new UserInfo(“James”, “Dean”, “MainStreet 21, NY”);


        Cache.Add(Guid.NewGuid().ToString(), u, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 5, 0), System.Web.Caching.CacheItemPriority.NotRemovable, new System.Web.Caching.CacheItemRemovedCallback(this.RemovedCallback));




References can exist in several places:

1.       In a registry of a thread:


0:022> !gcroot 0x14ef2a34

esi:Root:  14f002dc(System.Web.HttpResponse)->




2.       In the stack of a thread:


ESP:ef4f610:Root:  14f00194(System.Web.HttpContext)->

  … ->



3.       Within a GCHandle.

Different kind of handles can reference our objects:


          Strong Handles: they keep the object they point to alive until the handle is explicitly freed. Typically a static variable.


DOMAIN(001CAFF8):HANDLE(Strong):284118c:Root:  02b35d3c(System.Threading._TimerCallback)->

  … ->



          Pinned Handles: they are used to prevent the GC from moving an object during collection. Pinning objects can cause heap fragmentation.




          Weak Short Handles: they are non null as long as the object they reference is alive because of another Strong reference. They are null otherwise.




          Weak Long Handles: they are non null as long as the object they reference hasn’t been reclaimed by the GC. It can be resurrected.




The distinction between Weak Short and Weak Long comes from the finalization semantics: a Weak Short reference is null if the object can be freed, but a Weak Long reference still refers to the freachable object. 


4.       In an object ready for finalization.

The object is no longer in use but nobody called its Dispose method.


Finalizer queue:Root:


5.       As a member of an object found in 1, 2 or 3 above.

If our object is referenced by another one, it can’t be garbage collected. We should get rid of that reference or dispose the object that references ours.






If there is a live reference to an object, that object is said to be strongly rooted. .NET also introduces the notion of weakly rooted references. A weak reference provides a way for programmers to indicate to the GC that they want to be able to access an object, but they don’t want to prevent the object from being collected. Such an object is available until it is collected by the GC. For example, you could allocate a large object, and rather than fully deleting and collecting the object, you could hold onto it for possible reuse, as long as there is no memory pressure to clean up the managed heap. Thus, weak references behave somewhat like a cache.


·         We can calculate the size of an object:

We can see the size of an object including its child objects. For instance, to determine how much an ASP.NET app is caching, we can do the following:

0:028> !Name2EE * System.Web.Caching.Cache


Module: 6638c000 (System.Web.dll)

Token: 0x020000f7

MethodTable: 6639d878

EEClass: 6639d808

Name: System.Web.Caching.Cache


0:028> !DumpHeap -mt 6639d878


Heap 0

 Address       MT     Size

046b9198 6639d878       12    

total 1 objects


Heap 1

 Address       MT     Size

total 0 objects


total 1 objects


      MT    Count    TotalSize Class Name

6639d878        1           12 System.Web.Caching.Cache

Total 1 objects

0:028> !ObjSize 046b9198

sizeof(046b9198) =       319128 (     0x4de98) bytes (System.Web.Caching.Cache)


Next post: MANAGED DEBUGGING with WINDBG. Managed Heap. Part 4.

Index: MANAGED DEBUGGING with WINDBG. Introduction and Index.




Alex (Alejandro Campos Magencio) 

Comments (0)

Skip to main content