This article uses windbg to debug a simpleProgramTo clear the differences in the memory allocation methods of class type and value type in. NET Framework, and the role of methodtable, an important internal component of the object.
The source code used to explain the problem is as follows:
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 = 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
Set the debug attribute of the project to enabled unmanaged code debugging, set the breakpoint on line 31, press F5 to start debugging, and open the intermediate window to start windbg SOS debugging.
. 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
The following is a brief description of the each column:
MT-> methodtable. First, describe the role of methodtable. We know that each type can have multiple instances. In C ++, each instance and each field can have independent space, while a public method entry address is provided for the Type method. That is to say, no matter how many instances of the same type, they all point to the same function entry address. The entry addresses of each function are recorded in the function entry address description table. Methodtable has a similar effect. Since all assemblies are self-described, we can know the corresponding instance from methodtable. Therefore, use the corresponding DEBUG command! Dumpheap-MT mtaddress can be used to know all associated instances in methodtable.
Count-> Number of related objects under a specific methodtable address
Totalsize-> occupied space
Class Name-> Object descriptive information
See the following:
! 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
It can be seen that there are two related objects in the methodtable, one object address is: 0286168c, And the other object address is: 02861698
In. net, we know that for class type objects, the Object ref occupies space on the stack, while the Object ref points to the space on the GC heap. We already know that there are two vsdebug. testclass objects on heap, and their heap address is also given.
Next let's see if there is a corresponding vsdebug. testclass ref pointing to its object in the stack.
! DSO
OS thread ID: 0xed8 (3800)
ESP/REG Object Name
ECS x 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 [])
Sure enough, we can see two objects on the stack pointing to vsdebug. testclass on the heap :)