在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本文通过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 :) |
请发表评论