Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
181 views
in Technique[技术] by (71.8m points)

c# - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
  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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...