我有一个来自IIS进程的转储,它占用了近100%的CPU。我运行windbg并在运行!runaway
命令后,发现顶部线程都被卡在了FindEntry(System.__Canon)
命令中。其中一个线程的堆栈以:
0:043> !clrstack -p
OS Thread Id: 0x1740 (43)
Child SP IP Call Site
0000008646eecc78 00007ff810530c8a [RedirectedThreadFrame: 0000008646eecc78]
0000008646eecd10 00007ffffe420ccd System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].FindEntry(System.__Canon)
PARAMETERS:
this = <no data>
key = <no data>
0000008646eecd80 00007ffffe422ed4 System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].TryGetValue(System.__Canon, System.__Canon ByRef)
PARAMETERS:
this = <no data>
key = <no data>
value = <no data>
我怀疑我的问题类似this one,但在得出结论之前我需要更多的证据。为此,我希望我能获得有关字典的值或任何其他信息。看看这段代码,网上的大多数教程都有两点不同:
System.__Canon
。这是什么意思? TryGetValue
获取值,因为它只有一个引用(ByRef)到输出,而指针没有列在“参数”部分。提前致谢!
答案 0 :(得分:3)
您还没有共享源代码,而且您还没有写过您是否使用静态词典,所以我假设您不是。但是你怀疑你的词典是在线程之间共享的 - 让我们发现它。当您处于方法中间或代码高度优化时,CLRStack
通常无法找到参数。另一个非常有用的SOS命令是!DumpStackObjects
或!dso
。它只是转储堆栈中的所有托管对象。你可能会找到你的关键值(除非它是一个基本类型 - 然后事情会变得有点复杂,我需要更多的信息来帮助你)。示例输出可能如下所示:
OS Thread Id: 0x1520 (0)
ESP/REG Object Name
ecx 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
edx 020e218c System.String k1
esi 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BED6C 020e1228 System.String
005BED70 020e218c System.String k1
005BED78 020e45a4 System.IO.TextReader+SyncTextReader
005BED80 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BED90 020e217c System.Object[] (System.String[])
005BEDA0 020e1228 System.String
005BEDA4 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BEDA8 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BEDAC 020e21b4 System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]]
005BEDB8 020e21a0 System.String v1
005BEDBC 020e217c System.Object[] (System.String[])
005BEE40 020e217c System.Object[] (System.String[])
005BEFA4 020e217c System.Object[] (System.String[])
005BEFD4 020e217c System.Object[] (System.String[])
请注意,字典在列表中。对每个线程运行此命令,并验证它们是否共享字典地址。 System.__Canon
不是你应该担心的 - 它只是一般类型的占位符(http://referencesource.microsoft.com/#mscorlib/system/object.cs,a210e11a9e5f2deb)。在上面的输出中,我有一个Dictionary<String,String>
实例并且正在寻找 k1 - 因为你可以看到它也在堆栈中。