我有一个Web应用程序,有时它挂起/执行速度很慢。我使用DebugDiag进行了完全转储,并尝试使用Crash / Hang分析进行分析。
摘要告诉我,7.86%的线程(10)被阻止并等待Monitor.Wait
。
但是,当我用线程检查调用堆栈/堆栈跟踪时,输出以下内容:
.NET Call Stack
Function
System.Threading.Monitor.ObjWait(Boolean, Int32, System.Object)
System.Threading.Monitor.Wait(System.Object, Int32, Boolean)
Quartz.Simpl.SimpleThreadPool+WorkerThread.Run()
System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
System.Threading.ExecutionContext.runTryCode(System.Object)
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object)
System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
System.Threading.ThreadHelper.ThreadStart()
Full Call Stack
Function Source
ntdll!NtWaitForMultipleObjects+15
KERNELBASE!WaitForMultipleObjectsEx+100
kernel32!WaitForMultipleObjectsExImplementation+e0
clr!WaitForMultipleObjectsEx_SO_TOLERANT+56
clr!Thread::DoAppropriateAptStateWait+4d
clr!Thread::DoAppropriateWaitWorker+17d
clr!Thread::DoAppropriateWait+60
clr!CLREvent::WaitEx+106
clr!CLREvent::Wait+19
clr!Thread::Wait+1d
clr!Thread::Block+1a
clr!SyncBlock::Wait+169
clr!ObjHeader::Wait+2c
clr!ObjectNative::WaitTimeout+147
System.Threading.Monitor.Wait(System.Object, Int32, Boolean)
System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
System.Threading.ExecutionContext.runTryCode(System.Object)
clr!CallDescrWorker+33
clr!CallDescrWorkerWithHandler+8e
clr!MethodDesc::CallDescr+194
clr!MethodDesc::CallTargetWorker+21
clr!MethodDescCallSite::Call+1c
clr!ExecuteCodeWithGuaranteedCleanupHelper+bb
clr!ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup+138
System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
System.Threading.ThreadHelper.ThreadStart()
clr!CallDescrWorker+33
clr!CallDescrWorkerWithHandler+8e
clr!MethodDesc::CallDescr+194
clr!MethodDesc::CallTargetWorker+21
clr!ThreadNative::KickOffThread_Worker+1e1
clr!Thread::DoExtraWorkForFinalizer+114
clr!Thread::ShouldChangeAbortToUnload+101
clr!Thread::ShouldChangeAbortToUnload+399
clr!Thread::RaiseCrossContextException+3f8
clr!Thread::DoADCallBack+358
clr!Thread::DoExtraWorkForFinalizer+fa
clr!Thread::ShouldChangeAbortToUnload+101
clr!Thread::ShouldChangeAbortToUnload+399
clr!Thread::ShouldChangeAbortToUnload+43a
clr!ManagedThreadBase::KickOff+15
clr!ThreadNative::KickOffThread+23e
clr!Thread::intermediateThreadProc+4b
kernel32!BaseThreadInitThunk+e
ntdll!__RtlUserThreadStart+70
ntdll!_RtlUserThreadStart+1b
它实际上并没有显示他们正在等待获取哪个锁 - 有关如何获取此信息的任何想法吗?
答案 0 :(得分:1)
不幸的是,在调用Monitor.Wait之前,线程看起来并没有很多方法,因此可能更难确定确切的位置。基于堆栈跟踪,查看Quartz.Simpl.SimpleThreadPool + WorkerThread.Run()的代码,并查看它调用Monitor.Wait的位置以查看它实际等待的内容。
根据代码的数量/质量,这可能是最简单的方法。您还可以安装Windbg,找到它锁定的对象的地址,然后检查它,但是需要一些初始配置以确保它可以加载它需要的所有符号。 http://blogs.msdn.com/b/emeadaxsupport/archive/2011/04/10/setting-up-windbg-and-using-symbols.aspx谈论Windbg设置。它是一个功能强大的工具,但只是检查Quartz.Simpl.SimpleThreadPool + WorkerThread.Run()的代码可能会更简单。