基本上我们有一个ASP.NET MVC应用程序,它偶尔会有几个小时的请求挂起,导致累计的DeadThread数量累积。
我最后通过使用参数转储其中一个线程的CLRStack来达到最低点。
0:043> !CLRStack -p
OS Thread Id: 0x2010 (43)
Child SP IP Call Site
000000237ae4d6d0 000007fe81a1724d System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].Insert(System.__Canon, System.__Canon, Boolean)
PARAMETERS:
this = <no data>
key = <no data>
value = <no data>
add = <no data>
000000237ae4d760 000007fe84a56877 Microsoft.ApplicationInsights.TelemetryClient.Track(Microsoft.ApplicationInsights.Channel.ITelemetry)
PARAMETERS:
this (0x000000237ae4d7f0) = 0x0000001f9c954448
telemetry (0x000000237ae4d7f8) = 0x000000211ca5c840
000000237ae4d7f0 000007fe84db96de Lojaali.Services.Telemetry.AzureTelemetryService+c__DisplayClass9_0.b__0()
PARAMETERS:
this = <no data>
000000237ae4d8a0 000007fe829ab39e System.Threading.Tasks.Task.Execute()
PARAMETERS:
this (0x000000237ae4d910) = 0x000000211ca5cb68
000000237ae4d910 000007fe829aaf25 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
PARAMETERS:
executionContext = <no data>
callback = <no data>
state = <no data>
preserveSyncCtx = <no data>
000000237ae4da70 000007fe829aac7a System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
PARAMETERS:
executionContext = <no data>
callback = <no data>
state = <no data>
preserveSyncCtx = <no data>
000000237ae4daa0 000007fe829aa978 System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)
PARAMETERS:
this (0x000000237ae4db80) = 0x000000211ca5cb68
currentTaskSlot (0x000000237ae4db88) = 0x000000211ca765e8
000000237ae4db80 000007fe829aa610 System.Threading.Tasks.Task.ExecuteEntry(Boolean)
PARAMETERS:
this = <no data>
bPreventDoubleExecution = <no data>
000000237ae4dbc0 000007fe829a98ba System.Threading.ThreadPoolWorkQueue.Dispatch()
000000237ae4e128 000007fee0f9a7f3 [DebuggerU2MCatchHandlerFrame: 000000237ae4e128]
000000237ae4e2b8 000007fee0f9a7f3 [ContextTransitionFrame: 000000237ae4e2b8]
000000237ae4e4d8 000007fee0f9a7f3 [DebuggerU2MCatchHandlerFrame: 000000237ae4e4d8]
所以我特别对TelemetryClient.Tack调用感兴趣
000000237ae4d760 000007fe84a56877 Microsoft.ApplicationInsights.TelemetryClient.Track(Microsoft.ApplicationInsights.Channel.ITelemetry)
PARAMETERS:
this (0x000000237ae4d7f0) = 0x0000001f9c954448
telemetry (0x000000237ae4d7f8) = 0x000000211ca5c840
所以我开始转储其中包含的词典。对于他们中的大多数人,我得到了钥匙和价值。
然而,令我感到困惑的是,当我尝试转储包含用户属性的字典时,最后一个条目似乎已将键和值清零:
0:043> !DumpObj /d 0000001f9ca54ba0
Name: System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
MethodTable: 000007fe81fdc808
EEClass: 000007fe819eeef0
Size: 80(0x50) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
000007fe81b28ef8 4000ca4 8 System.Int32[] 0 instance 0000001f9ca54c08 buckets
000007fe81bb0bb8 4000ca5 10 ...non, mscorlib]][] 0 instance 0000001f9ca54c30 entries
000007fe819bf6f8 4000ca6 38 System.Int32 1 instance 2 count
000007fe819bf6f8 4000ca7 3c System.Int32 1 instance 288 version
000007fe819bf6f8 4000ca8 40 System.Int32 1 instance -1 freeList
000007fe819bf6f8 4000ca9 44 System.Int32 1 instance 0 freeCount
000007fe81a0f058 4000caa 18 ...Canon, mscorlib]] 0 instance 000000201c955ae8 comparer
000007fe81e7c618 4000cab 20 ...Canon, mscorlib]] 0 instance 0000000000000000 keys
000007fe81df1b38 4000cac 28 ...Canon, mscorlib]] 0 instance 0000000000000000 values
000007fe819b6088 4000cad 30 System.Object 0 instance 0000000000000000 _syncRoot
0:043> !DumpObj /d 0000001f9ca54c30
Name: System.Collections.Generic.Dictionary`2+Entry[[System.String, mscorlib],[System.String, mscorlib]][]
MethodTable: 000007fe81fdcd38
EEClass: 000007fe81fdcc90
Size: 96(0x60) bytes
Array: Rank 1, Number of elements 3, Type VALUETYPE (Print Array)
Fields:
None
0:043> !DumpArray /d 0000001f9ca54c30
Name: System.Collections.Generic.Dictionary`2+Entry[[System.String, mscorlib],[System.String, mscorlib]][]
MethodTable: 000007fe81fdcd38
EEClass: 000007fe81fdcc90
Size: 96(0x60) bytes
Array: Rank 1, Number of elements 3, Type VALUETYPE
Element Methodtable: 000007fe81fdcc18
[0] 0000001f9ca54c40
[1] 0000001f9ca54c58
[2] 0000001f9ca54c70
0:043> !dumpvc 000007fe81fdcc18 0000001f9ca54c70
Name: System.Collections.Generic.Dictionary`2+Entry[[System.String, mscorlib],[System.String, mscorlib]]
MethodTable: 000007fe81fdcc18
EEClass: 000007fe81a6b058
Size: 40(0x28) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
000007fe819bf6f8 4000cb2 10 System.Int32 1 instance 0 hashCode
000007fe819bf6f8 4000cb3 14 System.Int32 1 instance 0 next
000007fe819b6160 4000cb4 0 System.__Canon 0 instance 0000000000000000 key
000007fe819b6160 4000cb5 8 System.__Canon 0 instance 0000000000000000 value
这引出了我的问题。这怎么可能?这是正常还是我应该关注的事情?如果我应该关注,我在.NET代码中寻找什么来最终确定问题?