终结器队列的大小

时间:2014-03-13 22:07:48

标签: c# garbage-collection idisposable finalizer

如何在c#中获取终结器队列的当前大小?

我正在尝试调试一个过于宽松的应用程序,让垃圾收集器处理IDIsposables,我怀疑它与偶尔的崩溃有关。

有问题的IDIsposables包含非托管内存,因此实​​现自己的终结器,如果在垃圾收集之前没有明确调用Dispose方法,则会终止它们。

垃圾收集处理一个单独的终结器线程中的所有可终结对象,如果创建的对象比完成对象的速度快,则可以增长。

如果我能输出当前在程序的各个阶段等待最终确定的对象数量,那将是一个很大的帮助。

IDisposable对象来自各种库,因此将记录添加到各自的终结器本身并非易事。有没有办法直接从GC获取等待完成的对象数?

3 个答案:

答案 0 :(得分:1)

您可以使用内存性能计数器。 http://msdn.microsoft.com/en-us/library/x2tyfybc(v=vs.110).aspx

答案 1 :(得分:1)

要使用C#,您可以使用WMemoryProfiler,它可以自动从C#进行调试。如果您愿意,您甚至可以调试自己的流程:

using System;
using WMemoryProfiler;

namespace AllocateManyObjects
{
    /// <summary>
    /// Shows the basic usage of WMemoryProfiler
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // Start this application not under the debugger
                // To start is press Ctrl+F5 in Visual Studio to start it without debugging.

                SelfDebug();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Got Exception: {0}", ex);
            }
            Console.WriteLine("Press Enter to exit.");
            Console.ReadLine();
        }


        /// <summary>
        /// Issue a !Threads command and print the output to console
        /// </summary>
        private static void SelfDebug()
        {
            using (var debugger = new MdbEng())
            {
                string[] output = debugger.Execute("!FinalizeQueue");
                Console.WriteLine(String.Join(Environment.NewLine, output));
            }
        }
    }
}

您只需要下载https://wmemoryprofiler.codeplex.com/SourceControl/latest 编译源代码并从Windows 8.0 SDK安装Windbg或将其部署到它搜索Windbg的位置:

C:\ Program Files(x86)\ Windows Kits \ 8.0 \ Debuggers \ x64

C:\ Program Files(x86)\ Windows Kits \ 8.0 \ Debuggers \ x86

然后你可以解析sos命令的输出或做任何你想要的事情。

此示例在我的机器上打印:

0:008> !FinalizeQueue
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll -

************* Symbol Loading Error Summary **************
Module name            Error
clr                    The system cannot find the file specified : srv*c:\symbols*http://msdl.microsoft.com/download/symbols

You can troubleshoot most symbol related issues by turning on symbol loading diagnostics (!sym noisy) and repeating the command that caused symbols to be loaded.
You should also verify that your symbol search path (.sympath) is correct.
PDB symbol for clr.dll not loaded
SyncBlocks to be cleaned up: 0
Free-Threaded Interfaces to be released: 0
MTA Interfaces to be released: 0
STA Interfaces to be released: 0
----------------------------------
generation 0 has 165 finalizable objects (0000000000a70ed0->0000000000a713f8)
generation 1 has 0 finalizable objects (0000000000a70ed0->0000000000a70ed0)
generation 2 has 0 finalizable objects (0000000000a70ed0->0000000000a70ed0)
Ready for finalization 0 objects (0000000000a713f8->0000000000a713f8)
Statistics for all finalizable objects (including all objects ready for finalization):
              MT    Count    TotalSize Class Name
00007ff84e389230        1           24 System.WeakReference
00007ff84e3874a0        1           32 Microsoft.Win32.SafeHandles.SafePEFileHandle
00007ff84e397a28        1           88 System.Diagnostics.Tracing.EventSource+OverideEventProvider
00007ff84e36eca8        1          104 System.Runtime.Remoting.Contexts.Context
00007ff84e397600        1          160 System.Diagnostics.Tracing.FrameworkEventSource
00007ff84e38a5e0        6          192 Microsoft.Win32.SafeHandles.SafeWaitHandle
00007ff84e388038        3          192 System.Threading.ReaderWriterLock
00007ff84e384928        7          224 Microsoft.Win32.SafeHandles.SafeFileHandle
00007ff84d4298a8        8          256 Microsoft.Win32.SafeHandles.SafeProcessHandle
00007ff84e3822f8        4          384 System.Threading.Thread
00007ff84e3a15a0       17          544 Microsoft.Win32.SafeHandles.SafeTokenHandle
00007ff84e38ca60        7          728 System.IO.FileStream
00007ff84d43c908        8         2240 System.Diagnostics.Process
00007ff84d3f94d8      100         5600 System.Diagnostics.ProcessModule
Total 165 objects
0:008> .remote_exit g;
Press Enter to exit.

答案 2 :(得分:0)

您可以使用sos.FinalizeQueue命令