zoukankan      html  css  js  c++  java
  • 利用windbg调试class type,value type以及MethodTable等强化C#的基本概念

    本文通过windbg调试一个简单的程序,来清除说明.Net framework中class type,value type的内存分配方式的不同,以及object内部的重要组成MethodTable的作用

    用于说明问题的source code如下:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Collections;
     6 
     7 namespace VSDebug
     8 {
     9     class StringHolder
    10     {
    11         public string StringData;
    12         public StringHolder(string stringData)
    13         {
    14             StringData = stringData;
    15         }
    16     } 
    17 
    18     class  TestClass
    19     {
    20         public ArrayList Holders;
    21         [STAThread]
    22         static void Main(string[] args)
    23         {
    24             TestClass testClass = new TestClass();
    25             TestClass testClass1 = new TestClass();
    26             testClass.Holders = new ArrayList();
    27             for (int i = 0; i < 10++i)
    28             {
    29                 testClass.Holders.Add(new StringHolder("Hello"));
    30             }
    31             Console.ReadLine();
    32         } 
    33 
    34     }
    35 }
    36 

    设置project 的debug属性为enabled unmanaged code debugging,在31行设置breakpoint,然后press F5开始调试,并打开intermediate window开始windbg sos 调试

    .load sos

    extension C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll loaded

    !dumpheap -stat

    PDB symbol for mscorwks.dll not loaded

    total 2086 objects

    Statistics:

    MT Count TotalSize Class Name

    79100f58 1 12 System.Security.Permissions.SecurityPermission

    790fdc5c 1 20 System.Text.StringBuilder

    79104368 1 24 System.Collections.ArrayList

    790fcc48 1 24 System.Reflection.Assembly

    0023304c 2 24 VSDebug.TestClass

    790feba4 1 28 System.SharedStatics

    790fd0f0 3 36 System.Object

    790ff734 2 40 System.RuntimeType

    79100e38 1 44 System.Security.FrameSecurityDescriptor

    790ff120 1 44 System.AppDomainSetup

    7912dd40 1 64 System.Char[]

    79100a18 2 72 System.Security.PermissionSet

    790fe17c 1 72 System.ExecutionEngineException

    790fe0e0 1 72 System.StackOverflowException

    790fe044 1 72 System.OutOfMemoryException

    790fed00 1 100 System.AppDomain

    003c7508 7 100 Free

    002330cc 10 120 VSDebug.StringHolder

    790fe284 2 144 System.Threading.ThreadAbortException

    7912d8f8 9 8992 System.Object[]

    790fd8c4 2037 129576 System.String

    Total 2086 objects

    下面对each column作简要说明:

    MT-〉MethodTable. 首先说明MethodTable的作用。我们知道每种type可以有多个instance。在C++中,每个instance,其每个field可以享有独立的space,而对于type的method提供一个公共的method入口地址。也就是说不管多少个相同类型的instance,其都指向了同一个同一的函数入口地址。在这个函数入口地址描述表中记录了各个函数的入口地址。而MethodTable就有点类似的作用。自不过所有Assembly都是自描述的,因此我们可以从MethodTable中,可以知道相应的instance。因此通过相应的debug命令!dumpheap -mt MTAddress可以知道在MethodTable中相关联的所有instance了

    Count ->某个特定MethodTable地址下相关联的objects的数目

    TotalSize->所占空间

    Class Name->object descriptive information

    请看下面:

    !dumpheap -mt 0023304c

    Address MT Size

    0286168c 0023304c 12

    02861698 0023304c 12

    total 2 objects

    Statistics:

    MT Count TotalSize Class Name

    0023304c 2 24 VSDebug.TestClass

    Total 2 objects

    可以看出,在该MethodTable中关联的有2个objects,一个object address是:0286168c,而另外一个object address 是:02861698

    在.net中,我们知道,对于class type的object,其object ref是占用stack上的空间,而 object ref则指向了GC heap上的空间。刚才我们已经知道在heap上有2个VsDebug.TestClass的object,并且其Heap Address也已给出。

    下面看看在stack是否有相应的VsDebug.TestClass ref指向其object.

    !dso

    OS Thread Id: 0xed8 (3800)

    ESP/REG Object Name

    ecx 02861788 System.Object[]

    0014eef0 028616a4 System.Collections.ArrayList

    0014eef8 028617d8 VSDebug.StringHolder

    0014f064 028616a4 System.Collections.ArrayList

    0014f068 028617d8 VSDebug.StringHolder

    0014f06c 0286168c VSDebug.TestClass

    0014f074 02861788 System.Object[] (System.Object[])

    0014f29c 02861698 VSDebug.TestClass

    0014f2a4 02861660 System.Object[] (System.String[])

    0014f2bc 02861660 System.Object[] (System.String[])

    0014f394 02861660 System.Object[] (System.String[])

    0014f53c 02861660 System.Object[] (System.String[])

    0014f564 02861660 System.Object[] (System.String[])

    果然,可以看到在stack上看到2个指向heap上的VsDebug.TestClass 类型的object :) 

  • 相关阅读:
    让webpack打包支持ES7的async/await语法
    你的GitHub,怎么和我用的不太一样?
    你的GitHub,怎么和我用的不太一样?
    node.js koa 实现长轮询
    node.js koa 实现长轮询
    eggjs解决跨域问题
    ElementUI表单验证攻略:解决表单项启用和禁用验证的切换,以及动态表单验证的综合性问题
    个人对内存中对象中包含对象的理解
    PAT乙级1019
    PAT乙级1036
  • 原文地址:https://www.cnblogs.com/Winston/p/1340748.html
Copyright © 2011-2022 走看看