我有一个应用程序,经历从单词go缓慢的内存泄漏。我如何找到悬挂终结器队列的原因?
使用ANTS内存分析器我可以看到所有泄漏的内存都由终结器队列的GC根保存。
我怀疑可能发生的事情是终结器死锁,等待锁定变为可用状态。
我们的类都没有实现明确的终结器,我们通常会避免它们,这让我认为锁可能与系统或库类有关。
我用SOS.dll
来看看终结队列的内容,如果我正确地解释它,然后它报告的第一个项目,如果队列的头实际上代表是一个实例System.Threading.Thread
但是我不确定当前正在处理的对象或将要处理的下一个对象。
- 是否有任何技巧可以用来找出最终确定的内容?
- 有没有一种方法,我可以找出什么锁终结线程正在等待?
- 是否可以打开任何额外的调试来跟踪终结器线程的操作?
- 我还能看到什么?
更新
终结器线程的堆栈显示如下:
[email protected]() + 0x15 bytes
[email protected]() + 0x15 bytes
[email protected]() + 0x15 bytes
[email protected]() + 0x43 bytes
[email protected]() + 0x12 bytes
ole32.dll!GetToSTA() + 0x72 bytes
ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall() - 0x1939 bytes
ole32.dll!CRpcChannelBuffer::SendReceive2() + 0xa6 bytes
ole32.dll!CAptRpcChnl::SendReceive() + 0x5b7 bytes
ole32.dll!CCtxComChnl::SendReceive() - 0x14b97 bytes
ole32.dll!NdrExtpProxySendReceive() + 0x43 bytes
[email protected]@4() + 0xe bytes
rpcrt4.dll!_NdrClientCall2() + 0x144 bytes
[email protected]() + 0x7a bytes
[email protected]() + 0xf bytes
ole32.dll!CObjectContext::InternalContextCallback() - 0x511f bytes
ole32.dll!CObjectContext::ContextCallback() + 0x8f bytes
clr.dll!CtxEntry::EnterContext() + 0x119 bytes
clr.dll!RCWCleanupList::ReleaseRCWListInCorrectCtx() + 0x2bb bytes
clr.dll!RCWCleanupList::CleanupAllWrappers() - 0x20fb0 bytes
clr.dll!SyncBlockCache::CleanupSyncBlocks() + 0x1ec6 bytes
clr.dll!Thread::DoExtraWorkForFinalizer() + 0x411b5 bytes
clr.dll!WKS::GCHeap::FinalizerThreadWorker() + 0x8b bytes
clr.dll!Thread::DoExtraWorkForFinalizer() + 0xb6e76 bytes
clr.dll!Thread::ShouldChangeAbortToUnload() - 0x5f8 bytes
clr.dll!Thread::ShouldChangeAbortToUnload() - 0x53d bytes
clr.dll!ManagedThreadBase_NoADTransition() + 0x35 bytes
clr.dll!ManagedThreadBase::FinalizerBase() + 0xf bytes
clr.dll!WKS::GCHeap::FinalizerThreadStart() + 0xfb bytes
clr.dll!Thread::intermediateThreadProc() + 0x48 bytes
[email protected]@12() + 0x12 bytes
[email protected]() + 0x27 bytes
[email protected]() + 0x1b bytes
为什么你通常会避免使用终结器?正确执行一次性模式*需要*终结器。 – svick
@svick - 关于MSDN的说明。实施IDisposable说:“如果一个班级本身不拥有非托管资源,则完全不使用终结器” – chillitom
@svick - chillitom是正确的。引用[框架设计指南](http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613):“如果你能提供帮助,你真的不想写一个终结器。” – TrueWill