In the world of CLR, there are a series of amazing technologies and architectures. Among them, CLR allocates memory for the application in the memory, executes the model, and interacts with each other among other technologies, so every technical staff dedicated to the DOTNET platform deserves further research.
During the development process, if programmers load the Assembly (assemblies load), reflection (reflection), host (hosting), and application domain (appdomain ), if these four technologies are used together, they can not only better use the powerful functions provided by the CLR platform, but also build safer and more robust application code.
In this blog post, we use a dynamic debugging tool for hosting code to study the world of appdomain in CLR.
First, start with a C # program:
Class Program
{
Static void main (string [] ARGs)
{
Program B = new program ();
B. Test ();
System. Console. Readline ();
}
Public void test ()
{
Int I = 67;
System. Console. writeline (char) I );
System. Console. writeline (char) 67 );
I = 1;
}
}
After running this application, we open windbg and attach it to this managed process.
. Load SOS
To load the SOS extension debugging module, you can use the. Chain command to check whether the loading is correct.
0: 003> LM
Start end module name
00400000 00408000 testconcoleapp (deferred)
76990000 76acd000 OLE32 (deferred)
77be0000 77c38000 msvcrt (deferred)
Omitted
Fc770000 77fd1000 secur32 (deferred)
78130000 781cb000 msvcr80 (deferred)
79000000 79045000 mscoree (deferred)
79060000 790b3000 mscorjit (deferred)
790c0000 79b90000 mscorlib_ni (deferred)
79e70000 7a3d6000 mscorwks (deferred)
View the modules loaded by the artistic conception, and then use the LD command to load our debugging symbol file. When vs compiles and generates a console app, a PDB file with the same name as the app is generated under the bin directory of DEBUG in debug mode. All we need to do is load this file:
0: 003> LD testconcoleapp
* ** Warning: unable to verify checksum for G:/projects/testconcoleapp/bin/debug/testconcoleapp.exe
Symbols loaded for testconcoleapp
There is a warning. When you use LM to view the loaded modules, you can see that the debugging symbol file of this module has been loaded.
In this case, we can check what is in the stack of the excute engine (CLR). We can use it! The eeheap command EE refers to the CLI execution engine, which is also known as CLR. This command can view the garbage-collected and loader heaps information in a managed process.
0: 003>! Eeheap
PDB symbol for mscorwks. dll not loaded
Loader heap:
--------------------------------------
System domain: 7a38f918
Lowfrequencyheap: Size: 0x0 (0) bytes.
Highfrequencyheap: 00a62000 (8000: 1000) Size: 0x1000 (4096) bytes.
Stubheap: 00a6a000 (2000:1000) Size: 0x1000 (4096) bytes.
Virtual call stub heap:
Indcellheap: Size: 0x0 (0) bytes.
Lookupheap: Size: 0x0 (0) bytes.
Resolveheap: Size: 0x0 (0) bytes.
Dispatchheap: Size: 0x0 (0) bytes.
Cacheentryheap: Size: 0x0 (0) bytes.
Total size: 0x2000 (8192) bytes
/*************************************** *******
System domain in loader heap. This domain, together with the following shared domian, is invisible to hosted host programs and managed code. This field loads two modules that are very important in CLR execution, mscoree. dll and mscorwks. dll. Mscoree. dll is a familiar shim and shim. It plays an important role in CLR loading. I will not analyze it here. You can refer to the introduction of other documents.
Each application domain has its own security descriptor, security context, and default context. These three parts support an application domain to customize a separate security policy, for example, it can be used to ensure that host programs do not damage these important data structures when loading managed code.
**************************************** ******/
--------------------------------------
Shared domain: 7a38fef0
Lowfrequencyheap: 00a90000 (2000:1000) Size: 0x1000 (4096) bytes.
Highfrequencyheap: Size: 0x0 (0) bytes.
Stubheap: 00a9a000 (2000:1000) Size: 0x1000 (4096) bytes.
Virtual call stub heap:
Indcellheap: Size: 0x0 (0) bytes.
Lookupheap: Size: 0x0 (0) bytes.
Resolveheap: 00aab000 (5000: 1000) Size: 0x1000 (4096) bytes.
Dispatchheap: 00aa7000 (4000: 1000) Size: 0x1000 (4096) bytes.
Cacheentryheap: Size: 0x0 (0) bytes.
Total size: 0X4000 (16384) bytes
/*************************************** *******
In the shared domain, assemblies, such as mscorlib. dll, are used to load all application domains. The base classes such as system. Object and system. valuetype are loaded.
**************************************** ******/
--------------------------------------
Domain 1: 154250
Lowfrequencyheap: 00a70000 (2000:2000) Size: 0x2000 (8192) bytes.
Highfrequencyheap: 00a72000 (8000: 2000) Size: 0x2000 (8192) bytes.
Stubheap: Size: 0x0 (0) bytes.
Virtual call stub heap:
Indcellheap: Size: 0x0 (0) bytes.
Lookupheap: Size: 0x0 (0) bytes.
Resolveheap: Size: 0x0 (0) bytes.
Dispatchheap: Size: 0x0 (0) bytes.
Cacheentryheap: Size: 0x0 (0) bytes.
Total size: 0X4000 (16384) bytes
/*************************************** *******
For specific host programs, you can create default domains for multiple applications as needed. For example, ie, ASP. NET, or sqlserver, you can create one or more default domains. By default, the name of a domain name is the module name.
In the default domain, assemblies that need to be loaded during application execution can be loaded here.
In each application domain, the object created by the Code cannot directly access the code in another application domain. To access the code, you can use static delegation or the appdomain method.
**************************************** ******/
--------------------------------------
JIT code heap:
Loadercodeheap: 00db0000 () Size: 0x1000 (4096) bytes.
Total size: 0x1000 (4096) bytes
For hosted applications, there are two ways to compile the Il code at a cost. One is to call the JIT module to compile the code in real time during the first run, and put the compiled local code here. In the corresponding code in the PE file, we use a pointer to guide the CLR here to find the locally compiled code. Second, the local code is compiled during installation.
At the same time, we can see that JIT heap occupies a small amount of memory space.
--------------------------------------
Module thunk heaps:
Module 790c2000: Size: 0x0 (0) bytes.
Module 00a72c24: Size: 0x0 (0) bytes.
Total size: 0x0 (0) bytes
--------------------------------------
Module lookup table heaps:
Module 790c2000: Size: 0x0 (0) bytes.
Module 00a72c24: Size: 0x0 (0) bytes.
Total size: 0x0 (0) bytes
--------------------------------------
Total loaderheap size: 0xb000 (45056) bytes
The total loader heap size is approximately 45 KB.
========================================================
Number of GC heaps: 1
Generation 0 starts at 0x013b1018
Generation 1 starts at 0x013b100c
Generation 2 starts at 0x013b1000
Ephemeral segment allocation context: None
The following two segments are read only for other codes in the application domain. Therefore, the space for these two segments is relatively small. This part often stores small segement fragments. Unless you are a long and long string. Large objects are kept in LOH. GC heap, which can have multiple. Each GC heap can have a LOH.
The total size of each GC heap = space occupied by segment + Loh
Segment begin allocated size
0014d720 790d5588 790f4b38 0x0001f5b0 (128432)
013b0000 013b1000 013b3ff4 0x00002ff4 (12276)
Large Object heap starts at 0x023b1000
Segment begin allocated size
023b0000 023b1000 023b3250 0x00002250 (8784)
Total size 0x247f4 (149492)
------------------------------
GC heap size 0x247f4 (149492)
The total GC heap is about KB.
Bytes ---------------------------------------------------------------------------------------------------------
Memory Structure of the managed thread:
Here, the memory structure of the next managed process is handed over. After a thread is created for a hosted application, at least three application domains are created by default, namely system domains, shared domains, and default domains. The first two are invisible to hosted user code. At that time, you can call assemblies in the shared object. The user's managed code and modules are loaded to the default domain. A hosted host can create one or more default domains as needed.
Relationship between managed processes, threads (hard threads, soft threads), application domains, assemblies, and modules
The four concepts of managed processes, application domains, assembly, and modules are one-to-many relationships from left to right. And one hosting can correspond to multiple application domains, one appdomain can correspond to multiple assemblies, and one assembly can correspond to multiple modules. Modulesw.exe or. dll. EXE files are managed modules extended to the PE file format in windows. Modules can also be a hosted Dynamic Linked Library file.
This is a special case for threads. Here, we need to first distinguish between the thread created by the operating system process and the thread represented by the class system. Threading. thread. Here, the process created by the operating system is called hard thread, and the thread represented by the class system. Threading. thread is called soft thread. The relationship between hard thread and application domain is a multi-stack relationship. There can be multiple hard threads in an application domain. A hard thread can also exist in multiple application domains. The soft thread is created by assemblies in the application domain. Therefore, it only exists in the corresponding application domain.
When a system's hard thread enters an application domain for operations, this application domain will instantiate a system. Threading. Thread class to complete the corresponding work of this thread.
Environment variable attributes of the application domain:
For each application domain, you can set a series of environment attributes. By setting these attributes, you can configure the features of an application domain to meet various security requirements, performance and many other special requirements.
Refer to msdn here:
Http://msdn2.microsoft.com/en-us/library/system.appdomain_properties.aspx
Obtain all properties related to the application domain.
Note: The dynamic directory of the application domain:
For all attributes of the application domain, a property called dynamicdirectory needs to be mentioned in particular.
This property is generated in two parts, for example, the cache folder of an Asp.net host process on my local machine:
C:/Windows/Microsoft. NET/framework/v2.0.50727/Temporary ASP. NET files/mesapplication/8a8504fd/e1680364
C:/Windows/Microsoft. NET/framework/v2.0.50727/Temporary ASP. NET files/mesapplication, which is defined by a property called dynamic_base. It also contains information about the project files loaded in this application domain.
The following two parts are 8a8504fd/e1680364, which are determined by the app_name attribute of the application based on different project files.
In this case, the process is cached in the local folder during debugging.
In the next article, we will explain how to implement the appdomain running mechanism from the perspective of instance source code.