缓慢/挂起Asp.net Web应用程序 - 完全转储显示等待锁定的几个线程

时间:2012-11-01 08:13:09

标签: asp.net performance hang debugdiag

我有一个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 

它实际上并没有显示他们正在等待获取哪个锁 - 有关如何获取此信息的任何想法吗?

1 个答案:

答案 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()的代码可能会更简单。