I got the following question from a reader named “Bysza” in the form of a comment on post about “How to tackle memory issues in a server application”:

“I’m using this approach for some time now, but I not always succeed in finding roots to objects.
I’m looking for a method to find objects that hold reference to my live object which sould be already gone.

Could you help me in that matter?”

If I understand the question correctly, you want to be able to find who is holding your live objects.

If that is the case, its quite simple.
What you need to do is either take a memory dump (I explained a bit on how to use it in this post) or attach WinDbg to the relevant process.

After you loaded the dump or attached to the process perform the following operations:

  1. Run !dumpheap -type [Part of the full namespace of the object] for example:
    !dumpheap -type MyNamespace.MyObjectThis will get you a list of the live objects of that type.
  2. Take the address from the first colum (that’s the address of the object) of the relevant object and run the command !gcroot [Object Address], for example:
    !gcroot 0x235025aThis will show you the chain of references up to the root object that is holding your referencing your object.
    This chain contains the addresses of each object in the chain so you will be able to know exactly who is holding who and why.

If a rooted object is directly holding your object you need to check one of the following things:

  • Do you have some kind of a Static (Shared in VB.NET) object in the application? If you do, this object is rooted and therefore every object it referecnces will never die until the application’s process is closed.Usually people have some kind of a static collection in which they store various objects and in a lot of the cases they forget to remove the objects from the collection.
  • Do you specifically pin objects? Do you call GCHandle.Alloc ? If so, be sure to release those handles or make sure that the objects being pinned do not hold references to objects you want to release.

I hope this helps a bit. If not, post a comment and we will continue the discussion there.

If any of you have various questions as to issues raised in this blog or from personal experience, please write me an email to eran.sandler at gmail.com or leave a comment on one of the posts. Also, if any of you have some other comments about how did you implemet/use some of the things we have talked about here, I would love to hear about it.

  • Thank you for this post. I had an object that had a strong handle that pointed to itself. And the problem was that the object was actually pinned for access by unmanaged code.

    !gcroot -nostacks 5ccc31a4
    DOMAIN(002ED7E8):HANDLE(Strong):b11c6fc:Root: 5ccc31a4(MyNameSpace.DummyObject)