开发者

How to Identify where Instances of an object are Still Referenced?

After running the VS2010 profiler with Object Lifetime Tracking in my app, I have this on a particular class :

Number of Instances----------1 418 276

%Total Instances --------------------- %5.8

Total Bytes Allocated ------- 158 846 912

%Total Bytes -------------------------- %5.94

Gen 0 Instances Collected --------- 5 196

Gen 1 Instances Collected --------54 894

Gen 2 Instances Collected ----747 874

Instances Alive At End --------- 开发者_运维百科610 312

Gen 0 Bytes Collected ----------- 581 952

Gen 1 Bytes Collected ---------6 148 128

Gen 2 Bytes Collected ---------3 761 888

As you cans see, half of all created instances end up mainly as Gen 2, and the other half is staying alive until the end of the App. [ha, ha, ha, ha, staying alive, staying alive... -> Ok sorry, I could'nt resist...]

What bothers me is that these instances should have a very short lifetime (It's basically a datafield class - that could be a struct, but I preferred to make it a class to "activate" GC on it).

These instances are created by reading very large binary files (each line being a class/ a record) and passed via a small sized queue by delegate/event to workers that basically just read it, put it in queues (which are very regularly dequeued), and then terminate (background workers ending normally). I guess Events are unsubscribed to when workers no more exist.

So, is there a way to identify where are these references hiding ? Because if they are not GC'd they ARE still referenced somewhere, but how to tell for sure ? I'm tired of guessing and trying so many hypothesis SO if somebody has more rational guidelines or a fair checklist and/or tools / precise profiler places to look at, I welcome it.

Complementary Resources to the Answers

Visual GCRoot via DGML - Thanks to Richard Szalay

Also, this video GCRoot Demo from Chris Lovett is very educative on the subject.


  1. Enable Unmanaged Debugging in the "Debug" tab of your project properties
  2. Run the application and set a breakpoint at a point where you want to investigate the types
  3. In the Immediate window, type:
.load sos
!DumpHeap -type <partial type name>

This will return something like:

 Address       MT     Size
026407c0 53ecee20       16     

Then you can take the Address and use GCRoot to find the where it's rooted:

!GCRoot 026407c0

Chris Lovett (via Tess Ferrandez) created a very neat utility that converts the low-level GCRoot output into a DGML graph which might make it easier to diagnose.

Alternatively, Mohamed Mahmoud created a debugger extension that enables you generate the graph from WinDBG, but it doesn't work within Visual Studio so you might want to stick to Chris's utility to avoid installing the Debugging Tools.

Having said that, the textual output may well be enough for you to track things down. If you want information on the output of GCRoot, type !help GCRoot in the immediate window.


EDIT 2018: if you have visual studio 2015+ then the whole process is much simpler: MSDN tutorial.

if you want to know exactly which instances are alive , all you need to do is take a process dump with Adplus, that comes with the debugging tools for windows. (its now part of the SDK download.)

then in WinDBG, use the !dumpheap -type command to see what instaces of which classes are still up.

then you can use the !gcroot to see who is holding that reference.


You can type the command gcroot.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜