完成队列卡住

时间:2013-06-26 08:49:52

标签: c# .net garbage-collection windbg finalizer

最近我们发现我们的一个服务器应用程序(因此它的Windows服务)因OutOfMemory异常而失败。我们试图找出发生了什么,最后我们最终确定了最终化队列中的对象,因此不会对它们进行垃圾收集。我们试图找出哪个终结器可以通过使用Windbg导致这种行为,但我们无法找出究竟是哪个对象导致它。

通过使用!finalizequeue命令我们可以找到:


    0:053> !finalizequeue
    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 28 finalizable objects (050eab4c->050eabbc)
    generation 1 has 15 finalizable objects (050eab10->050eab4c)
    generation 2 has 658 finalizable objects (050ea0c8->050eab10)
    Ready for finalization 3027 objects (050eabbc->050edb08)
    ...

3027是一个令人难以置信的高数字(运行几分钟后,这个数字仍然在增长而且从未下降)。我试图找出哪个对象在地址050eabbc上,但它总是不同类型所以我认为这不是原因。

如果我尝试打印终结器线程的本机调用堆栈,我得到了这个:


    0:053> ~2k
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SYSTEM32\KERNELBASE.dll - 
    ChildEBP RetAddr  
    WARNING: Stack unwind information not available. Following frames may be wrong.
    032ef09c 772f10b4 ntdll!ZwWaitForSingleObject+0xc
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SYSTEM32\combase.dll - 
    032ef0b0 755ff0b5 KERNELBASE!WaitForSingleObject+0x12
    032ef0e4 7554b22a combase!NdrOleDllGetClassObject+0x1399
    032ef108 755ff10c combase!PropVariantCopy+0x177b
    032ef224 75511724 combase!NdrOleDllGetClassObject+0x13f0
    032ef27c 7558115d combase!DcomChannelSetHResult+0x17c7
    032ef2d8 755fd39a combase!CoRegisterSurrogateEx+0x3494
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SYSTEM32\RPCRT4.dll - 
    032ef2f4 76a9e4a0 combase!NdrExtStubInitialize+0x21a9
    032ef71c 755fc779 RPCRT4!NdrComplexArrayUnmarshall+0xcac
    032ef738 75510d77 combase!NdrExtStubInitialize+0x1588
    032ef748 755816d5 combase!DcomChannelSetHResult+0xe1a
    032ef7dc 75587aa5 combase!CoRegisterSurrogateEx+0x3a0c
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll - 
    032ef82c 748ab680 combase!StringFromIID+0x28d
    032ef92c 748ab758 clr!PreBindAssemblyEx+0x259d
    032ef964 7487960d clr!PreBindAssemblyEx+0x2675
    032ef980 748ab55a clr!GetMetaDataInternalInterfaceFromPublic+0x2162a
    032ef9dc 74878915 clr!PreBindAssemblyEx+0x2477
    032efa2c 7487887c clr!GetMetaDataInternalInterfaceFromPublic+0x20932
    032efa44 7478a5e2 clr!GetMetaDataInternalInterfaceFromPublic+0x20899
    032efa8c 74777d71 clr!GetPrivateContextsPerfCounters+0x968

终结器线程始终停留在ZwWaitForSingleObject上,因此这是终结器线程卡住的另一个线索。

所以我的问题是,如何找出导致终结器队列卡住的对象?有趣的是,我根本不使用终结器: - (

1 个答案:

答案 0 :(得分:4)

我的心灵调试"猜测是在STA线程上运行的某些代码会创建一个COM对象,但该STA线程不会遵循COM规则重新消息(也许线程完全消失)。我之所以这么说,是因为我们在终结器的调用堆栈中看到了一些问题。显然,您需要适当的符号并查看本机和托管调用堆栈:

.symfix C:\localsymbolcache .reload ~2s kb !clrstack

如果您想重新提出此问题,请回复结果。