我试图理解存储在方法表中的信息。这是我的代码。
class MyClass
{
private int x = 60;
private int y = 90;
public void MethodB()
{
Console.WriteLine("MethodB");
}
public void MethodC()
{
Console.WriteLine("MethodC");
}
public void MethodA()
{
GetHashCode();
Monitor.Enter(this);
Console.WriteLine("Attach debugger now");
Console.ReadKey();
}
static void Main(string[] args)
{
MyClass mc = new MyClass();
mc.MethodA();
}
}
以下是对象在内存中的显示方式
0:000> !do 0x02368a1c
Name: ConsoleApplication1.MyClass
MethodTable: 001f3310
EEClass: 001f136c
Size: 16(0x10) bytes
(C:\Download\PresentationPrep\TechDaysDemos\SomeTesting\bin\Debug\SomeTesting.exe)
Fields:
MT Field Offset Type VT Attr Value Name
6d032da0 4000001 4 System.Int32 1 instance 60 x
6d032da0 4000002 8 System.Int32 1 instance 90 y
然后我转储方法表
0:000> dd 001f3310
001f3310 00000000 00000010 00050011 00000004
001f3320 6d030770 001f2f2c 001f334c 001f136c
001f3330 00000000 00000000 6cf86ab0 6cf86ad0
001f3340 6cf86b40 6cff7540 008500d0 00000080
001f3350 00000000 00000000 00000000 00000000
001f3360 00000000 00000000 00000000 00000000
001f3370 00000000 00000000 00000000 00000000
001f3380 00000000 00000000 00000000 00000000
这是我发现有点令人困惑的事情。
第一个字段表示对象的类型(如果是类或数组等)。我的理解是,对于课程,此字段显示0x00040000
,而此处仅显示0x00000000
。
第二个字段是对象的大小。这个没问题。
第三个字段00050011
的重要性是什么?
这个表示继承方法的数量,它们指向父对象类方法ToString
,Equals
,GetHashCode
和Finalize
。这是对的吗?
我不了解其他领域,所以如果有人解释这些领域,我们将非常感激。
答案 0 :(得分:1)
这基本上是一个实现细节,试图通过在内部结构周围探索CLR是如何工作的并不容易说。许多内部结构以各种方式进行优化,这使得倾向于相关信息变得困难。我有similar question here。
如果你还没看过,我建议你阅读Shared Source CLI essentials。虽然它没有涵盖所有血腥细节,但它确实很好地解释了共享源CLI的组织方式。
根据我的经验,如果不使用实用程序方法来封装CLR在内部执行的操作,则无法轻松映射其中某些结构。这基本上就是SOS为我们所做的事情。如果您获得SSCLI的来源,则可以深入了解SOS共享源版本的源代码以获取更多详细信息。
当然SSCLI与当前的Microsoft CLR不同,但根据我的经验,它们有很多共同点,所以它通常是一个很好的信息来源。
详细介绍了如何在.NET 1.x here中实现方法表。它有很多细节,但是实现已经改变,所以它对当前的CLR无效。
答案 1 :(得分:1)
只需使用
!sos.dumpmt 001f3310
这将为您提供Method表转储,您不必担心可在版本和SP之间更改的内部存储器布局