Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   CLR Hosting

The .NET Framework runs on top of Windows. This means that the .NET Framework must be built using technologies that Windows can interface with. For starters, all managed module and assembly files must use the Windows portable executable (PE) file format and be either a Windows executable (EXE) file or a DLL.

When developing the CLR, Microsoft implemented it as a COM server contained inside a DLL; that is, Microsoft defined a standard COM interface for the CLR and assigned GUIDs to this interface and the COM server. When you install the .NET Framework, the COM server representing the CLR is

registered in the Windows registry just as any other COM server would. If you want more information about this topic, refer to the MetaHost.h C++ header file that ships with the .NET Framework SDK. This header file defines the GUIDs and the unmanaged ICLRMetaHost interface definition.

Any Windows application can host the CLR. However, you shouldn’t create an instance of the CLR COM server by calling CoCreateInstance; instead, your unmanaged host should call the CLRCreateInstance function declared in MetaHost.h. The CLRCreateInstance function is implemented in the MSCorEE.dll file, which is usually found in the C:\Windows\System32 directory. This DLL is affectionately referred to as the shim, and its job is to determine which version of the CLR to create; the shim DLL doesn’t contain the CLR COM server itself.

A single machine may have multiple versions of the CLR installed, but there will be only one ver- sion of the MSCorEE.dll file (the shim).1 The version of MSCorEE.dll installed on the machine is the ver- sion that shipped with the latest version of the CLR installed on the machine. Therefore, this version of MSCorEE.dll knows how to find any previous versions of the CLR that may be installed.

The actual CLR code is contained in a file whose name has changed with different versions of the CLR. For versions 1.0, 1.1, and 2.0, the CLR code is in a file called MSCorWks.dll, and for version 4, the CLR code is in a file called Clr.dll. Because you can have multiple versions of the CLR installed on a single machine, these files are installed into different directories as follows.2

■ Version 1.0 is in C:\Windows\Microsoft.NET\Framework\v1.0.3705

 

■ Version 1.1 is in C:\Windows\Microsoft.NET\Framework\v1.0.4322

 

■ Version 2.0 is in C:\Windows\Microsoft.NET\Framework\v2.0.50727

 

■ Version 4 is in C:\Windows\Microsoft.NET\Framework\v4.0.21006

 

The CLRCreateInstance function can return an ICLRMetaHost interface. A host application can call this interface’s GetRuntime function, specifying the version of the CLR that the host would like to create. The shim then loads the desired version of the CLR into the host’s process.

 
 

1 If you are using a 64-bit version of Windows, there are actually two versions of the MSCorEE.dll file installed. One version is the 32-bit x86 version, which will be located in the C:\Windows\SysWOW64 directory. The other version is the 64-bit x64 or IA64 version (depending on your computer’s CPU architecture), which will be located in the C:\Windows\ System32 directory.



2 Note that versions 3.0 and 3.5 of the .NET Framework were shipped with version 2.0 of the CLR; I do not show the di- rectories for .NET Framework versions 3.0 and 3.5 because the CLR DLL loads from the v2.0.50727 directory.


By default, when a managed executable starts, the shim examines the executable file and ex- tracts the information indicating the version of the CLR that the application was built and tested with. However, an application can override this default behavior by placing requiredRuntime and supportedRuntime entries in its XML configuration file (described in Chapter 2, “Build- ing, Packaging, Deploying, and Administering Applications and Types,” and Chapter 3, “Shared Assemblies and Strongly Named Assemblies”).

The GetRuntime function returns a pointer to the unmanaged ICLRRuntimeInfo interface from which the ICLRRuntimeHost interface is obtained via the GetInterface method. The hosting ap- plication can call methods defined by this interface to:

■ Set Host managers. Tell the CLR that the host wants to be involved in making decisions related to memory allocations, thread scheduling/synchronization, assembly loading, and more. The host can also state that it wants notifications of garbage collection starts and stops and when certain operations time out.

■ Get CLR managers. Tell the CLR to prevent the use of some classes/members. In addition, the host can tell which code can and can’t be debugged and which methods in the host should be called when a special event—such as an AppDomain unload, CLR stop, or stack overflow exception—occurs.

■ Initialize and start the CLR.

 

■ Load an assembly and execute code in it.

 

■ Stop the CLR, thus preventing any more managed code from running in the Windows process.

 

There are many reasons why hosting the CLR is useful. Hosting allows any application to offer CLR features and a programmability story and to be at least partially written in managed code. Any application that hosts the runtime offers many benefits to developers who are trying to extend the application. Here are some of the benefits:

■ Programming can be done in any programming language.

 

■ Code is just-in-time (JIT)–compiled for speed (versus being interpreted).

 

■ Code uses garbage collection to avoid memory leaks and corruption.

 

■ Code runs in a secure sandbox.

 

■ The host doesn’t need to worry about providing a rich development environment. The host makes use of existing technologies: languages, compilers, editors, debuggers, profil- ers, and more.

If you are interested in using the CLR for hosting scenarios, I highly recommend that you get Steven Pratschner’s excellent book, Customizing the Microsoft .NET Framework Common Language Runtime (Microsoft Press 2005), even though it focuses on pre-4 versions of the CLR.


 

 

 
 

AppDomains

When the CLR COM server initializes, it creates an AppDomain. An AppDomain is a logical container for a set of assemblies. The first AppDomain created when the CLR is initialized is called the default AppDomain; this AppDomain is destroyed only when the Windows process terminates.

In addition to the default AppDomain, a host using either unmanaged COM interface methods or managed type methods can instruct the CLR to create additional AppDomains. The whole purpose of an AppDomain is to provide isolation. Here are the specific features offered by an AppDomain:

Objects created by code in one AppDomain cannot be accessed directly by code in an- other AppDomainWhen code in an AppDomain creates an object, that object is “owned” by that AppDomain. In other words, the object is not allowed to live beyond the lifetime of the AppDomain whose code constructed it. Code in other AppDomains can access another AppDomain’s object only by using marshal-by-reference or marshal-by-value semantics. This enforces a clean separation and boundary because code in one AppDomain can’t have a direct reference to an object created by code in a different AppDomain. This isolation allows AppDomains to be easily unloaded from a process without affecting code running in other AppDomains.


AppDomains can be unloadedThe CLR doesn’t support the ability to unload a single as- sembly from an AppDomain. However, you can tell the CLR to unload an AppDomain, which will cause all of the assemblies currently contained in it to be unloaded as well.

AppDomains can be individually securedWhen created, an AppDomain can have a per- mission set applied to it that determines the maximum rights granted to assemblies running in the AppDomain. This allows a host to load some code and be ensured that the code cannot corrupt or read important data structures used by the host itself.

AppDomains can be individually configuredWhen created, an AppDomain can have a bunch of configuration settings associated with it. These settings mostly affect how the CLR loads assemblies into the AppDomain. There are configuration settings related to search paths, version binding redirects, shadow copying, and loader optimizations.

       
   
 
 

 

Figure 22-1 shows a single Windows process that has one CLR COM server running in it. This CLR is currently managing two AppDomains (although there is no hard-coded limit to the number of App- Domains that could be running in a single Windows process). Each AppDomain has its own loader heap, each of which maintains a record of which types have been accessed because the AppDomain was created. These type objects were discussed in Chapter 4, “Type Fundamentals;” each type object in the loader heap has a method table, and each entry in the method table points to JIT-compiled na- tive code if the method has been executed at least once.

In addition, each AppDomain has some assemblies loaded into it. AppDomain #1 (the default AppDomain) has three assemblies: MyApp.exe, TypeLib.dll, and System.dll. AppDomain #2 has two assemblies loaded into it: Wintellect.dll and System.dll.

You’ll notice that the System.dll assembly has been loaded into both AppDomains. If both App- Domains are using a single type from System.dll, both AppDomains will have a type object for the same type allocated in each loader heap; the memory for the type object is not shared by all of the AppDomains. Furthermore, as code in an AppDomain calls methods defined by a type, the method’s Intermediate Language (IL) code is JIT-compiled, and the resulting native code is associated with each AppDomain; the code for the method is not shared by all AppDomains that call it.


Not sharing the memory for the type objects or native code is wasteful. However, the whole pur- pose of AppDomains is to provide isolation; the CLR needs to be able to unload an AppDomain and free up all of its resources without adversely affecting any other AppDomain. Replicating the CLR data structures ensures that this is possible. It also ensures that a type used by multiple AppDomains has a set of static fields for each AppDomain.

 

Windows Process

       
   

 
 

 
 

FIGURE 22-1A single Windows process hosting the CLR and two AppDomains.

 

Some assemblies are expected to be used by several AppDomains. MSCorLib.dll is the best ex- ample. This assembly contains System.Object, System.Int32, and all of the other types that are so integral to the .NET Framework. This assembly is automatically loaded when the CLR initializes, and all AppDomains share the types in this assembly. To reduce resource usage, MSCorLib.dll is loaded in an AppDomain-neutral fashion; that is, the CLR maintains a special loader heap for assemblies that are loaded in a domain-neutral fashion. All type objects in this loader heap and all native code for meth- ods of these types are shared by all AppDomains in the process. Unfortunately, the benefit gained

by sharing these resources does come with a price: assemblies that are loaded domain-neutral can never be unloaded. The only way to reclaim the resources used by them is to terminate the Windows process to cause Windows to reclaim the resources.



Date: 2016-03-03; view: 789


<== previous page | next page ==>
Nbsp;   Monitoring and Controlling the Lifetime of Objects Manually | Accessing Objects Across AppDomain Boundaries
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.011 sec.)