The CLR's Execution Model, clrexecution
Microsoft. NET Framework introduces many concepts, technologies, and terms. In this chapter, my goal is to give you an overview ,. NET Framework is designed to introduce some of the technologies included in the Framework, and many defined terms when you start to use. NET Framework. I will also build your own source code application or include (class, enumeration, and so on) a reusable component (file set) set) explain how an application is executed.
Compiling Source Code into Managed Modules(Compile the source code to the managed module)
You have decided to use. NET Framework as your development platform. Your first step is to decide which type of application or component you want to develop. Let's assume that you have completed this small detail. Everything has been designed, the specification has been written, and you are ready to develop.
Now you must decide which development language to use. Generally, this task is difficult because different languages have different capabilities. For example, for an unmanaged C/C ++, you can control the underlying system. You can precisely manage the memory in the way you want, it is easy to create a thread, and so on. Microsoft Visual Basic 6.0, on the other hand, allows you to quickly create UI applications and allows you to easily control COM components and databases.
The Common Language runtime Library (CLR) is the same as its name: runtime can be used in different and various programming languages. Core features of CLR (such as memory management, assembly loading, security, exception handling, and thread synchronization) can be applied to any and all programming languages as long as they are CLR during compilation. For example, runtime reports errors using exceptions, so all compilation targets are runtime programming languages to obtain error reports through exceptions. Another example is that runtime allows you to create threads. Therefore, all programming languages whose compilation target is runtime can create threads.
In fact, in the runtime Library, CLR does not know which development language the developer uses to write the source code. This means that the development language you choose should be the easiest way to express your intent. You can use any development language you want to use as long as your compiler can program your code into CLR.
So, what are the advantages of using a development language instead of another? Well, I think the compiler serves as a syntax reviewer and an analyst of "code correction. They check your source code, make sure that the source code you write has some truth, and then output the code that describes your intention. Different programming languages allow you to use different syntaxes during development. Do not underestimate the value of choosing a development language. For example, for mathematical or financial applications, using the APL syntax to express your development intent can save many days of development time to express the same development intent as using the Perl syntax.
Microsoft has created several language compilers to compile them into runtime: C ++, CLI, C # (pronounced "C sharp"), Visual Basic, F # (Pronunciation "F sharp"), Iron Python, Iron Ruby, and IL assembly. Apart from Microsoft, several other companies and universities have created compilers and the Code target is CLR. I know that compilers can compile languages such as Ada, APL, Caml, COBOL, Eiffel, Forth, Fortran, Haskell, Lexico, LISP, LOGO, Lua, Mercury, ML, Mondrian, oberon, Pascal, Perl, PHP, Prolog, RPG, Scheme, SmallTalk, and Tcl/Tk.
Pointed out that the program compiles the source code file ., You can use any programming language that supports CLR to create source code file sets. Then you can use the appropriate compiler to check the syntax and analyze the source code. No matter which compiler you use, the results are managed components. A hosted module is a standard 32-bit Windows PE32 file or a standard 64-bit Windows PE32 + file that can only be executed in CLR. By the way, hosting program assembly in Windows has the benefits of DEP and ASLR, which improve the security of your entire system.
The chart describes the components of the hosting module.
Managed Components
Component name |
Description |
PE32 or PE32 + header |
Standard Windows PE File Header, which is very similar to the header File of COFF (Common Object File Format. If the header file uses PE32 for conversion, the converted file can be run on a 32-bit or 64-bit Windows system. If the header file is converted to PE32 +, the file can only run on a 64-bit Windows system. The header file also specifies the file format: GUI, CUI, or DLL, and contains the timestamp when a file is created. For modules that only contain IL code, most of the information in the PE32 (+) header file will be ignored. For modules that contain local CPU code, this header file contains information about local CPU code. |
CLR header |
Contains information that marks the current module as a managed module (information interpreted by CLR and tools ). The header file contains the required CLR version, some tags, and the MethodDef metadata token at the entry point of the managed module method (Main method. The location and size of module metadata, resources, strong names, some tags, and a few other interesting things. |
Metadata |
Each managed module contains a metadata form. There are two main types in all forms: one is to describe the types and Members defined in your source code, and the other is to describe the referenced types and members in the source code. |
IL Coder |
The Code Compiled by the compiler. During running, CLR compiles the IL command at a cost. |
The local code compiler generates code based on the specified CPU architecture, such as x86, x64, or ARM. All compliance with the CLR compiler will generate IL. (I will go into more details about the IL Code in the following sections .) IL code is sometimes classified as managed code because CLR manages its execution.
Except for generating IL, each CLR-based compiler requires that all metadata be generated in each managed module. In short, metadata is a collection of data tables that describes what is defined in the module, such as the type and members. In addition, metadata also indicates reference of managed modules, such as the Import Type and members. Metadata is a superset of the old technology, such as the COM's Type Libraries and Interface Definition Language (IDL) files. Note that CLR metadata is more complete. In addition, unlike Type Libraries and IDL, metadata is always associated with files containing IL code. In fact, metadata is always embedded into the EXE/DLL with the same name as the Code, so that the EXE/DLL with the same name cannot be separated. Because the compiler binds metadata and code to the managed module at the same time, the metadata and IL Code cannot be described separately.
The following are some usage of metadata:
* During compilation, metadata removes the local C/C ++ header file and library file, because all types/member reference information is included in IL, and IL implements the type/member. The compiler can read metadata directly from the managed module.
* Microsoft Visual Studio uses metadata to help you write code. Its smart reminder feature tells you the attributes, events, and field types required by the method by converting metadata, and what parameters are required for the method.
* The CLR code verification program uses metadata to ensure the type security during code execution.
* Metadata allows fields of an object to be serialized as memory blocks, sent to another machine, and then deserialized to recreate the object state on a remote machine.
* Metadata allows the Garbage Collector to track the object lifecycle. For any object, the garbage collector can determine the type of the object. Through metadata, it can know which object contains fields that are referenced by another object.
In Chapter 2, "Generate, package, deploy, manage programs and types", I will talk about more metadata details.
Microsoft's C #, Visual Basic, F #, and IL explorer always generate modules that contain managed code (IL) and managed data (reclaim data type. To execute modules that contain hosted code or data, end users must install CLR on their machines (currently.. NET Framework). Similarly, they also need to install the Microsoft Foundation Class (MFC) library or Visual Basic DLLs to run the MFC or Visual Basic 6.0 program.
By default, Microsoft's C ++ compiler generates modules that contain unmanaged (local) Code and can operate unmanaged data (local memory) EXE/DLL at runtime. These modules do not require CLR execution. In any case, by specifying CLR command line conversion, the modules generated by the C ++ compiler will contain hosted code, so that you need to install CLR to execute the code. All Microsoft compilers mentioned that C ++ is the only compiler that allows programmers to write hosted and unmanaged code in a single module. C ++ is also the only language in Microsoft compiler that allows developers to define hosted and unmanaged Data Types in the source code. Compared with other compilers, Microsoft's C ++ compiler has unparalleled flexibility, because it allows developers to use existing locally hosted C/C ++ code and start to integrate with developers to see the appropriate hosting type.
Combining Managed Modules into Assemblies(The combined hosting module is an assembly)
CLR depends on the Assembly instead of the module. Assembly is an abstract concept that is hard to comprehend at the beginning. First, an assembly is a logical group that corresponds to one or more modules or source file sets. Second, an assembly is the minimum reusable, secure, and versionable unit. Depending on the compiler or tool you use, you can choose to generate a file or multi-file assembly. In the CLR world, an assembly is what we call a component.
In Chapter 2, I will review the Assembly in great detail, so I don't plan to spend too much time on the Assembly. What I want to do now is to let you know an additional concept, an idea of treating a group of files as an entity.
It should help explain what the Assembly is. In this figure, some managed modules are source files (or data) processed by a tool. Each time this tool generates a separate PE32 (+) file, it represents a logically grouped file set. This PE32 (+) file contains a piece of data called a cargo bill. The freight bill is a simple collection of metadata tables. These tables describe how files form a collection of programs. Publicly exported files are in the collection, and resources or data files are associated with the collection.
Note:The Assembly generated using the Microsoft C # compiler of version 1.0 or version 1.1 will contain a PE32 header file that is unrelated to the CPU architecture. In any case, the CLR considers that these sets only generate x86. For execution files, this increases the possibility that the application can indeed work on a 64-bit operating system, because the executable file will load WoW64 and give the process a similar environment to 32-bit x86.
If an unmanaged application calls the Win32 LoadLibrary function to load the hosted assembly, Windows knows to load and initialize the CLR (if not loaded) to process the code containing the assembly. Of course, in this scenario, the program has been started and run, and may affect the availability of the Assembly. For example, opening the x86 switch on the solution platform will never load the compiled hosted assembly to a 64-bit program. Otherwise, enabling the x86 switch on a computer running 64-bit Windows will load the executable files compiled in WoW64.
Executing Your Assembly's Code(Execute your assembly code)
As mentioned earlier, managed Assembly contains metadata and IL. IL is a machine language independent of CPU. After several discussions with external business and academic speech compiler writers, Microsoft created it. IL is a relatively advanced language than most CPU machine languages. IL can access and manipulate object types and issue instructions to create and initialize objects, call Virtual Methods in objects, and directly operate on array elements. It can even issue commands to handle exceptions. You can think of IL as an object-oriented machine language.
Generally, developers use an advanced language, such as C #, Visual Basic, or F #. The compiler generates IL for these advanced languages. Naturally, like other machine languages, ILMS can also be used to compile and write languages, and the ilasm.exe can be omitted. Microsoft also compiled an il, ildasm.exe.
Remember, any advanced language can only expose a subset of CLR tools. However, the IL assembly language allows developers to access all CLR tools. Therefore, when you want to select a CLR hidden tool that is advantageous to you for your programming language, you can choose to use IL assembly to write your part of code or another programming language that contains the features you need.
The only way to understand what tools CLR provides is to read the documents provided by CLR itself. In this book, I try to focus on CLR features and how to expose or not to expose these features through the C # language. I guess most other books or articles will present CLR in a language perspective, and most developers believe that the tools exposed by CLR are limited to the languages chosen by developers. This vague opinion is not a bad thing as long as your language permits you to accomplish what you want.
Key PointsI think the ability to integrate simple conversion development languages between languages is a great feature of CLR. Unfortunately, I also believe that developers often ignore this feature. Development languages such as C # and Visual Basic are good languages for performing I/O operations. It is a good language for executing advanced engineering or financial computing APL. Through CLR, you can use C # To write the I \ O section in your application, and use APL to write the Engineering Computing Section. CLR provides a layer of integration between these programming languages, which is unprecedented. In some projects, mixed language programming is worth considering. |
To execute a method, its IL must first convert the local CPU command. This is the work of the CLR real-time compiler (just-in-time compiler.
The example shows what happened when the method is called for the first time.
Only before calling the Main method, CLR checks all types referenced by the Main code. This is because the CLR allocates an internal data structure to manage access to the reference type. In, the Main method applies to a single-type Console. The reason for becoming single-type is that the CLR allocates a single internal structure. After being defined in the Console type, the internal structure of each method contains an entry. Each entry holds the implementation address of a method. When initializing this structure, the CLR sets each entry to internal, and the CLR itself contains non-document functions. I call this function JITCompliler (JIT compiler ).
When Main calls WriteLine for the first time, the JITCompiler function is called. The JITCompiler function is used to generate local CPU commands for the IL code of the compilation method. Because IL is compiled in real time, the CLR component is often classified as a JITter or JIT compiler.
Note:If the application runs on Windows x86 or WoW64 technology, the JIT compiler generates x86 commands. If your application is a 64-bit version and runs on Windows x64, the JIT compiler generates x64 commands. If the application runs on Windows of the ARM version, the JIT compiler generates the ARM command. |
Call a method for the first time
If (numberOfCPUs> 1 ){...}
These codes can cause the JIT compiler to not generate any CPU command, if the host has only one CPU. In this case, the local code will be fine-tuned for the host; the result code will be smaller and then executed faster.
* CLR can provide code execution outlines and re-compile the IL code at a cost when the application is running. Depending on the observation and execution model forecast, the re-compilation code can be reorganized to reduce the error branch. The current version of CLR does not work, but the future version may.
These are several reasons for your expectation that future managed code will be better executed than today's unmanaged code. As I said, most applications now have enough performance and will improve over time.
If your experiment shows that the clr jit compiler does not provide the performance required by your application, you may need to use the ngen.exe tool loaded in. NET Framework sdk. This tool compiles all the IL code in the Assembly and saves the result to a file stored on the disk. During runtime, when the Assembly is loaded, CLR automatically checks whether a pre-compiled version of the Assembly exists. If yes, the CLR loads the pre-compiled code and does not need to compile it at runtime. The ngen.exegion is reserved for the hypothetical execution environment. For this reason, the code generated by ngen.exe will not be highly optimized as the code generated by the JIT compiler. I will discuss it later in this chapter