最近,我们发现我们的服务器应用程序之一(因此是Windows服务)因OutOfMemory异常而失败。我们试图找出正在发生的事情,最后在finalize队列中的对象没有被finaled,因此它们上不会发生垃圾收集。我们试图找出哪些终结器可以通过使用Windbg导致此行为,但我们无法找出正是哪个对象导致了此行为。
通过使用!finalizequeue命令,我们可以找到以下内容:
0:053>!finalizequeue
未加载clr.dll的PDB符号
SyncBlocks需要清除:0
即将发布的自由线程接口:0
要发布的MTA接口:0
即将发布的STA接口:0
----------------------------------
第0代具有28个可终结对象(050eab4c-> 050eabbc)
第1代有15个可终结对象(050eab10-> 050eab4c)
第2代具有658个可终结对象(050ea0c8-> 050eab10)
准备完成3027个对象(050eabbc-> 050edb08)
...
3027的数字非常高(运行了几分钟后,这个数字仍在增长并且从未下降)。我试图找出哪个对象位于地址050eabbc上,但是它始终是不同的类型,因此我认为不是原因。
如果我尝试打印终结器线程的本机调用堆栈,则会得到以下信息:
0:053>〜2k
***错误:找不到符号文件。默认情况下为C:\ Windows \ SYSTEM32 \ KERNELBASE.dll导出符号-
ChildEBP RetAddr
警告:堆栈展开信息不可用。以下框架可能是错误的。
032ef09c 772f10b4 ntdll!ZwWaitForSingleObject + 0xc
***错误:找不到符号文件。默认情况下为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
***错误:找不到符号文件。默认为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
***错误:找不到符号文件。默认情况下为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上,因此这是终结器线程卡住的另一个线索。
所以我的问题是,如何找出导致终结器队列卡住的对象?有趣的是,我根本不使用终结器:-(
最佳答案
我的“心理调试”猜测是,在STA线程上运行的某些代码创建了COM对象,但是STA线程不遵循COM规则重新进行消息泵送(也许线程完全消失了)。我之所以这么说是因为我们在终结器的调用堆栈上看到了combase。显然,您需要适当的符号并查看本机和托管调用堆栈:.symfix C:\localsymbolcache.reload~2skb!clrstack
如果您想重新提出此问题,请发回结果。