1

我正在调查生产中的内存泄漏问题并检索了内存转储。我正在尝试转储我遇到的累积对象的值WeakReference。这是我在 WinDBG 中得到的:

0:000> !do 000000011a306510 
Name:        System.WeakReference
MethodTable: 000007feeb3f9230
EEClass:     000007feeadda218
Size:        24(0x18) 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
000007feeb3f4a00  400068d        8        System.IntPtr  1 instance         343620e0 m_handle
0:000> !do 343620e0 
<Note: this object has an invalid CLASS field>
Invalid object

我们可以发现我们不能使用该m_handle值作为对象地址。我检查了代码,WeakReference它是完整的extern代码。

我的问题是,我们如何使用 WinDBG/SOS 检查它的价值?另外,我正在为 ClrMD 的问题编写临时分析器,那么我应该如何检查对象的对象引用WeakReference呢?

4

2 回答 2

7

m_handle是一个IntPtrwhich 是一个值类型,所以获取IntPtrusing的方法表!name2ee *!System.IntPtr,然后执行

!dumpvc <method table of IntPtr> <value of m_handle>

这将为您提供IntPtr积分的价值。由于它指向一个对象,只需转储它

!do <value of IntPtr>
于 2015-10-22T22:25:41.780 回答
2

感谢托马斯的回答。

WeakReference下面是通过ClrMD 中的对象获取对象地址引用的代码:

private static readonly ClrType WeakRefType = Heap.GetTypeByName("System.WeakReference");
private static readonly ClrInstanceField WeakRefHandleField = WeakRefType.GetFieldByName("m_handle");
private static readonly ClrType IntPtrType = Heap.GetTypeByName("System.IntPtr");
private static readonly ClrInstanceField IntPtrValueField = IntPtrType.GetFieldByName("m_value");

private static ulong GetWeakRefValue(ulong weakRefAddr)
{
    var handleAddr = (long)WeakRefHandleField.GetValue(weakRefAddr);
    var value = (ulong)IntPtrValueField.GetValue((ulong)handleAddr, true);

    return value;
}

希望能帮助到你。

于 2015-10-23T16:31:54.853 回答