Debugging .NET memory leaks - how to know what is holding a reference to what?

后端 未结 5 1782
眼角桃花
眼角桃花 2021-01-02 13:12

I am working on a .NET application where there appears to be a memory leak. I know the text-book answers, that events should be unsubscribed, disposable objects should be di

相关标签:
5条回答
  • 2021-01-02 14:00

    The finalizer isn't deterministically called, so beware of using it to track things in a reliable way. If you remove the finalizer and instead use a WeakReference<Foo> you should be able to determine whether the object was collected.

    All memory profilers should be able to find an issue such as this, but with varying degree of difficulty. I have personally used ANTS which is very easy yo use, but not free. It will help you show a reference diagram to the Foo instance, all the way from a GC root object. Seeing this diagram it is usually easy to spot who is holding the reference.

    0 讨论(0)
  • 2021-01-02 14:00

    Firstly you shouldn't use a finalizer, because:

    Finalize operations have the following limitations:

    • The exact time when the finalizer executes during garbage collection is undefined. Resources are not guaranteed to be released at any specific time, unless calling a Close method or a Dispose method.

    • The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other. That is, if Object A has a reference to Object B and both have finalizers, Object B might have already finalized when the finalizer of Object A starts.

    • The thread on which the finalizer is run is unspecified.

    Quote from: http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx
    I would suggest using Dispose method instead.

    Secondly, any memory profiler should be able to find what holds those references. Personally I was using ANTS Profiler, it's a very nice tool and has quite rich documentation. You can try reading this doc: http://downloads.red-gate.com/HelpPDF/ANTS_Memory_Profiler/InstanceCategorizer.pdf Instance categorizer displays chains of references from sets of objects to GC root.

    0 讨论(0)
  • 2021-01-02 14:04

    Debugging memory leaks can be quite involved process and requires thorough understanding of your program logic and at least some .Net internals (especially garbage collector behaviour).

    For more information see the following links:

    Good introduction

    • http://msdn.microsoft.com/en-us/library/ee658248.aspx

    Hands-on course:

    • http://www.dotnetfunda.com/articles/article508.aspx
    • http://www.dotnetfunda.com/articles/article524.aspx

    GC and .Net internals

    • http://blogs.msdn.com/b/tess/archive/2008/04/17/how-does-the-gc-work-and-what-are-the-sizes-of-the-different-generations.aspx
    • http://msdn.microsoft.com/en-us/magazine/cc163491.aspx
    • http://blogs.msdn.com/b/maoni/archive/2004/06/03/148029.aspx

    WinDbg with SOS extension

    • http://www.codeproject.com/Articles/19490/Memory-Leak-Detection-in-NET
    • http://www.simple-talk.com/dotnet/.net-framework/investigating-.net-memory-management-and-garbage-collection/

    Good Luck!

    0 讨论(0)
  • 2021-01-02 14:09

    Have a look at the SOS debugger extension (It's free, an can be used within Visual Studio).

    You may find this and this helpful to get startet.

    If you have succefully set up SOS (this can be tricky sometimes), knowing what holds a reference to what is as easy as

    // load sos
    .load sos
    // list of all instances of YourTypeName in memory with their method tables
    !DumpHeap -type YourTypeName  
    // put here the method table displayed by the previous command
    // it will show you the memory address of the object
    !DumpHeap -mt 07f66b44              
    // displays information about references the object at the specified address
    !GCRoot 02d6ec94
    
    0 讨论(0)
  • 2021-01-02 14:16

    You can use memory profilers to identify the memory leaks. Here are some,

    MemProfiler

    ANTS Profiler

    0 讨论(0)
提交回复
热议问题