现在的位置: 首页 > 综合 > 正文

.Net 2.0内存对象布局详析及与1.1变化比较

2013年01月18日 ⁄ 综合 ⁄ 共 3941字 ⁄ 字号 评论关闭

写本文主要两个目的,一个是解析下2.0下的对象在内存里面究尽是个什么样子的布局,使用windbgsosshow下内存里面的bit是如何组织其来的。另外一个就是比较下和.Net Framework 1.1你面的内存布局有什么区别,修正下“Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects”里面的很多说法在Framework 2.0下面的不同的地方。

好久以前整的东西,这会给记录下来。表笑话,现在都

 

首先找个小的C#的演示程序:

namespace CLRLayoutTest2._0

{

    class Program

    {

        static int TestStaticFields = 1221119;

        static object TestStaticObject = new object();

 

        static string TestStaticMethod()

        {

            return "Test Static Method";

        }

 

        static void Main(string[] args)

        {

            Program a = new Program();

            a.Test();

            System.Console.ReadLine();

        }

 

        public void Test()

        {

            int i = 2;

            object testObject = (object)i;

 

            System.Console.WriteLine(testObject.ToString());

            System.Console.WriteLine(TestStaticFields.ToString());

 

        }

    }

}

 

好,设置好在.Net Framework 2.0的环境下给编译了。然后设置好windbg的调试环境,接着给attach上去:

0:000> !dso

OS Thread Id: 0x79c (0)

ESP/REG  Object   Name

0012f3c4 013f37b8 Microsoft.Win32.SafeHandles.SafeFileHandle

0012f3d4 013f37b8 Microsoft.Win32.SafeHandles.SafeFileHandle

0012f408 013f3854 System.Byte[]

0012f40c 013f37cc System.IO.__ConsoleStream

0012f430 013f37fc System.IO.StreamReader

0012f434 013f37fc System.IO.StreamReader

0012f438 013f16e8 CLRLayoutTest2._0.Program

0012f448 013f37fc System.IO.StreamReader

0012f44c 013f3b70 System.IO.TextReader+SyncTextReader

0012f450 013f16e8 CLRLayoutTest2._0.Program

0012f460 013f3b70 System.IO.TextReader+SyncTextReader

0012f464 013f16e8 CLRLayoutTest2._0.Program

0012f46c 013f16e8 CLRLayoutTest2._0.Program

0012f478 013f16cc System.Object[]    (System.String[])

0012f534 013f16cc System.Object[]    (System.String[])

0012f6e0 013f16cc System.Object[]    (System.String[])

0012f708 013f16cc System.Object[]    (System.String[])

 

看到咱的Program了,接着就看看013f16e8里面都有些啥呢,

0:000> !objsize 013f16e8

sizeof(013f16e8) = 12 (0xc) bytes (CLRLayoutTest2._0.Program)

 

好吧,12个字节,lesgo,查看memory

013f16e8 0000000000a83060 7910229000000000

013f16f8 0000000000000002 00000000790fd0f0

 

给标出来的部分,就是CLRLayoutTest2._0.Program这个type的一个instance object在内存里面的内容。

这个地方,稍微再说说一个object instance在内存你面的结构,在以前的文章里面有详细说过这个东西的。一个instance的前2个字节,保存的是SyncBlk,这个是和同步相关的东西,其实现原理和lock是一样的,flier曾经写过文章讲SyncBlk的实现原理和过程,感兴趣的可以去看看。接着下来的2个字节,保存的就是type handle,也就是我们经常说的obj ref,对一个对象的引用其实就是指到这个的方的。这个例子里面,显示的是00a83060

 

我们可以来验证下:

0:000> !do 013f16e8

Name: CLRLayoutTest2._0.Program

MethodTable: 00a83060

EEClass: 00a811f4

Size: 12(0xc) bytes

 (E:/myProject/CLRLayoutTest2.0/CLRLayoutTest2.0/bin/Debug/CLRLayoutTest2.0.exe)

Fields:

      MT    Field   Offset            Type    Attr   Value Name

79102290  4000001       1c    System.Int32  static  1221119 TestStaticFields

790fd0f0  4000002        4   System.Object   static 013f16dc TestStaticObject

 

可以看到,这个对象的MethodTable: 00a83060,就是在object instance的数据空间的第5个字节开始起,四个字节存放的地方。79102290这个内存地址show的东西,就是这个typeinstanceinstance data。可以在上面的Fields区域里面看到,指类型变量,不包括ref type的数据的MT,都会在这个的方给show出来。0000000000000002,一个四个字节大小的空间,正是一个System.Int32的大小,

 

一个object在内存你面主要的东西,包括object instance,以及保存这个object重要结构的MethodTable,还有保存和object对应的typeEEClass。这三个东西,构成了内存里面一个object的主要内容。接下来看看主要数据结构MethodTable及其变化。

 

0:000> !dumpmt -md 00a83060

EEClass: 00a811f4

Module: 00a82c3c

Name: CLRLayoutTest2._0.Program

mdToken: 02000002  (E:/myProject/CLRLayoutTest2.0/CLRLayoutTest2.0/bin/Debug/CLRLayoutTest2.0.exe)

BaseSize: 0xc

ComponentSize: 0x0

Number of IFaces in IFaceMap: 0

Slots in VTable: 9

--------------------------------------

MethodDesc Table

   Entry MethodDesc      JIT Name

79371278   7914b928   PreJIT System.Object.ToString()

7936b3b0   7914b930   PreJIT System.Object.Equals(System.Object)

7936b3d0   7914b948   PreJIT System.Object.GetHashCode()

793624d0   7914b950   PreJIT System.Object.Finalize()

00a8c011   00a83038     NONE CLRLayoutTest2._0.Program.TestStaticMethod()

00db00c0   00a83040      JIT CLRLayoutTest2._0.Program.Main(System.String[])

00db0148   00a83048      JIT CLRLayoutTest2._0.Program.Test()

00db0118   00a83050      JIT CLRLayoutTest2._0.Program..ctor()

00db0070   00a83058      JIT CLRLayoutTest2._0.Program..cctor()

 

上面是SOS解析好了内存之后列出的内存结构,使用quad Hex格式显式出来的,可能不是很好辨认,下面换一种内存

抱歉!评论已关闭.