Search code examples
c#performancegarbage-collectiondisposefinalizer

How can I investigate finalization queue and finalization survivors


I'm investigating GC and memory use in our application, and have noticed we seem to have thousands of finalization survivors. Unfortunately, the number alone doesn't really tell me whether we have a problem. We are seeing general performance issues however, and we do have high memory use and spend a lot of time in GC.

Ideally, nothing we have any control over should enter the finalization queue. It's a bug if it does. Is there some method or tool I can use to check this? One suggestion I've heard is to have a special build with finalizers that log whenever they are executed, but this is quite a lot of effort, and will only work with the objects whose types we own. Is there an easier way?

And is it worth investigating finalization survivors? If so, how?


Solution

  • Use WinDbg with Psscor2 or Psscor4 extension (depending version used by you application). Unfortunately there is no version for .NET 4.5 yet. After setting up the debugging environment (installing WinDbg and copying to its folder Psscor files), create a dump of the process. You can do it easily for example with help of Procdump tool:

    procdump -ma <PID>
    

    Then load dump using File -> Open Crush Dump option. Load appropriate version of Psscor:

    .load psscor4
    

    Then execute command to download symbols from Microsoft servers (if needed), make sure that you have an internet connection:

    !symfix
    

    And from now you should have access to plenty very interestings command (look for !help to list them). To see finalization queue:

    !finalizequeue
    

    There you will have a list of object, like:

    7aa143e0      166       20,584 System.Diagnostics.PerformanceCounter
    79b5f6c8      543       21,720 System.Reflection.Emit.DynamicResolver
    673893a8      953       22,872 System.Web.HttpResponseUnmanagedBufferElement
    

    This might help you a lot. But you can also inspect those objects (!do 7aa143e0), find references (!gcroot <address>) etc.