Windbg/sos:查找哪个类具有对对象的静态引用
我正在排除内存泄漏问题,发现一个对象被保存在内存中,因为它被字典引用。当我对字典实例执行 !gcroot 时,唯一固定的句柄是 System.Object[] 数组,它本身是无根的:
0:025> !gcroot -nostacks 38ad01f8
DOMAIN(0000000002287D80):HANDLE(Pinned):11e15c0:Root: 00000000123c5018(System.Object[])->
0000000002f2ab20(System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[MyApp.MyObject, MyApp]])->
000000004223e6e0(System.Collections.Generic.Dictionary`2+Entry[[System.String, mscorlib],[MyApp.MyObject, MyApp]][])->
0000000038ad01f8(MyApp.MyObject)
这使我得出结论,字典实例由某个类 (. NET 将所有静态字段引用保留在对象数组中)。
但是,现在我陷入困境,因为 !gcroot 和 !refs (来自 sosex)看不到静态字段引用。
我可以在堆中搜索指向地址 2f2ab20 的指针:
0:025> s-q 0 L?0xbfffffff 2f2ab20
00000000`123c76f8 00000000`02f2ab20 00000000`02f2ab78
所以我看到地址 123c76f8 附近的某个结构正在引用我的字典。但我该去哪里呢? 123c76f8 附近的结构必须由 EEClass 结构指向,但 sos/sosex 似乎没有提供解析哪个 EEClass 相关的方法。
如果没有这些信息,我如何找出哪个对象包含静态字典?
I'm troubleshooting a memory leak and found that an object is being held in memory because it is referenced by a dictionary. When I do a !gcroot on the dictionary instance, the only pinned handle is an array of System.Object[] which itself is unrooted:
0:025> !gcroot -nostacks 38ad01f8
DOMAIN(0000000002287D80):HANDLE(Pinned):11e15c0:Root: 00000000123c5018(System.Object[])->
0000000002f2ab20(System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[MyApp.MyObject, MyApp]])->
000000004223e6e0(System.Collections.Generic.Dictionary`2+Entry[[System.String, mscorlib],[MyApp.MyObject, MyApp]][])->
0000000038ad01f8(MyApp.MyObject)
This leads me to conclude that the Dictionary instance is being held by a static field on some class (.NET keeps all static field references in an Object array).
However, now I'm stuck because !gcroot and !refs (from sosex) do not see static field references.
I can search the heap for a pointer to the address 2f2ab20:
0:025> s-q 0 L?0xbfffffff 2f2ab20
00000000`123c76f8 00000000`02f2ab20 00000000`02f2ab78
So I see that some structure near the address 123c76f8 is referencing my dictionary. But where do I go from here? The structure near 123c76f8 must be pointed to by an EEClass structure, but sos/sosex don't seem to provide a way to resolve which EEClass is relevant.
Without that information, how can I figure out which object contains a static dictionary?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
进行此类分析的一种选择是使用 NuGet 上的 ClrMD 库编写一个小程序来运行转储或进程。
该程序如下所示:
您可以在 DotNet 博客
One option for doing this sort of analysis is to use the ClrMD libraryon NuGet to write a small program to run over a dump or process.
The program would look like this:
You can read more about the ClrMD library here on the DotNet blog
我运行该 博客。
版本:
Win7 X64 .NET 4
我把我的结果贴在这里仅供大家参考。这是我读完博客后第二次验证结果。第一次验证没有得到预期的结果。
I run the code that is post on that blog.
version:
Win7 X64 .NET 4
I post my result here just for your reference. this is my second time to verify the result after reading the blog. The first time verifying is not got the expected result.
本博客中描述了一种方法。该方法的简短解释是您想要找到一段将新元素添加到对象数组中的代码。该对象数组是静态字段数组(在您的情况下为 00000000123c5018 )。该方法的名称应该是 AnOffendingType..ctor(),它是您正在寻找的静态类型构造函数。
One method described in this blog. A short explanation of the method is you want to locate a peice of code that added a new element into an object array. That object array is array of static fields (00000000123c5018 in your case). The name of the method is supposed to be AnOffendingType..ctor(), which is a static type constructor you are looking for.