Sunday, November 22, 2009  
Google
Web pcquest.com

CIOL Network sites

Search by Issue | Sitemap | Advanced Search

• For most updated version of DQ TOP 20 issue, visit dqindia.com • Ad : Play and Plug ERP by IBM

Home > Developers Lab > CLR Internals

    Enterprise Solutions
    Hands On
    ITstrategy

    Developer

    Tech Forum

    SMB Forum

    Trends

    Shootout

    Reviews
    Editorials
    Linux and Open Source
    Technology
    Extraedge

    IT Careers

    Vertical Focus

Subscribe to Print magazine.


now!


Newsletter


CLR Internals

The CLR is at the heart of the .Net platform


Monday, December 31, 2001

The CLR (Common Language Runtime) is the platform on which applications written in multiple languages can run in a secure, efficient and robust manner. It provides the developers with a set of services so that they can focus on writing their code and leave the management of memory, metadata, and other common chores to the system.

We’ll now delve into the internals of the CLR. We’ll start with a simple program and refine it to show the various services offered by the runtime to the developer.

Figure 1 shows a program written in C# output a message to the console.

Figure 1:
*Allow easy reference to classes in the System namespace*
using System;
*This “class” exists only to house the application’s entry-point function*
class MainApp {
*Static method called “Main” is application’s entry point function*
public static void Main() { *Write text to the console Console.*
WriteLine(“The NET NET of DOTNET is that it ROCKS!!”); 
}
}

There are two interesting features about this program. First, the ‘using system’ line tells the runtime that we are using system services, in this case, writing to the console. Included with .Net will be a base-class library that contains several class definitions, where each class exposes some feature of the underlying platform. Since Microsoft defines literally hundreds of classes in the base library, the library is divided into namespaces that group related classes together.

For example, the System namespace (which you should become most familiar with) contains the base class, Object, which all other classes ultimately derive from. In addition, the System namespace contains classes for exception handling, garbage collection, console I/O, as well as a bunch of utility classes that convert safely between data types, format data types, generate random numbers, and perform various math functions.

To access any of the platform’s features, you need to work with these namespaces and their defined classes. If you want to customize the behavior of any class, you can simply derive your own class from the desired base library class.

Secondly, when the C# compiler is used to compile this file it produces an executable which has intermediate language or MSIL stored in it. The same code as shown in Figure 1 is shown in intermediate language format in Figure 2.

Figure 2:
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Code size 11 (0xb)
.maxstack 8
IL_0000: ldstr 
“The NET NET of DOTNET is that it ROCKS!!”
IL_0005: call void [mscorlib]System.Console::WriteLine(string)
IL_000a: ret
} // end of method MainApp::Main

MSIL is much higher level than most CPU machine languages. It understands object types and has instructions that create and initialize objects, call virtual methods on objects, and manipulate array elements directly. It even has instructions that raise and catch exceptions for error handling. The important thing to note about MSIL is that it is not tied to any specific CPU platform. This means that an executable file containing MSIL can run on any CPU platform as long as the operating system running on that CPU platform hosts the .Net common language runtime engine. Initially, Microsoft will offer the runtime on the Windows platform.

Of course, the MSIL instructions cannot be executed directly by today’s host CPUs. So, the common language runtime engine must first compile the MSIL instructions into native CPU instructions.

When the common language runtime loads a class, it connects stub code to each method. When a method is called, the stub code directs program execution to the component of the common language runtime engine that is responsible for compiling the method’s MSIL into native code. Since the MSIL is being compiled just-in-time (JIT), this component of the runtime is frequently referred to as a JIT compiler or JITter. Once the JIT compiler has compiled the MSIL, the method’s stub is replaced with the address of the compiled code. Whenever this method is called in the future, the native code will just execute and the JIT compiler will not have to be involved in the process. As you can imagine, this offers significant performance benefits. This process is shown in Figure 3.

Figure 3:
Source --> Language Compiler --> MSIL --> JIT Compiler --> Native Code

Next, let us modify the program to do the same functionality but use a helper class to achieve it. Figure 4 shows the same program as Figure 1, but this time the class to output the message resides in an external module.

Figure 4:
*Allow easy reference to classes in the System namespace*
using System;
*Refer to the external class that will output to the console*
using OutputMessage;
*This “class” exists only to house the application’s entry-point function
class MainApp {
*Static method called “Main” is application’s entry point function*
public static void Main() {
*Create an instance of a class that will output to the console*
OutputMessage outMsg = new OutputMessage();
*Call the function that will output to the console*
outMsg->PrintMessage();
}
}

Figure 5 shows the “OutputMessage” class that is defined in an external module. This module (a dll) is referenced when compiling the main application.

Figure 5:
*A helper class defined in a separate module from the main application*
class OutputMessage {
*This function outputs to the console*
public void PrintMessage() {
*Write text to the console*
Console.WriteLine(“The NET NET of DOTNET is that it ROCKS!!”); 
}
}

Now, when we run the main application, the common language runtime has to load the module that contains the ‘OutputMessage’ class. This enables the main application to create an instance of this class and call functions on it. This is done by a component of the runtime called the Class Loader. The job of the class loader is to locate the appropriate version of the module that contains the classes needed by the application. It can search for these modules in the application directory, in a directory specified in a configuration file, a shared location called the Global Assembly Cache or GAC, or download it from a site.

The other interesting feature of this program is that even though the programmer called ‘new’ to allocate the instance of class ‘OutputMessage’ she did not call ‘delete’ to reclaim the memory. This may not be new to VB programmers but is certainly new to C++/COM programmers. One of the most common bugs occurs in a C++/COM application when it neglects to free one of the resources, like memory, causing that application or others to perform improperly or crash at some unpredictable time. The CLR automatically tracks resource usage, guaranteeing that your application never leaks resources. This facility is called automatic resource management or Garbage Collector. The runtime has a high performance, scalable garbage collector that frees up memory only when it requires additional memory. This ensures that the performance of the application is not adversely affected. In fact, in some scenarios the garbage collector can improve the performance of the application by locating frequently used objects nearby in memory.

Let us refine this program further to illustrate two important features of CLR, namely, error-handling and multi-threading. Figure 6 shows the same application as Figure 4 but this time it spawns a thread which can execute in parallel with the main thread. Each of these threads, outputs a message to the console and exits.

Figure 6:
*Allow easy reference to classes in the System namespace*
using System;
*Refer to the external class that will output to the console*
using OutputMessage;
*Refer to the threading classes
using System.Threading;
* This “class” exists only to house the application’s entry-point function*
class MainApp {
*Static method called “Main” is application’s entry point function*
public static void Main() { 
*Try to create two threads which output to the console. In case of an*
error an exception is raised.*
try { 
*Create an instance of a class that will output to the console*
OutputMessage outMsg = new OutputMessage();
*PrintMessage is the secondary thread’s entry point.*
Thread t = new Thread(new ThreadStart(outMsg.PrintMessage));
*Start the thread* t.Start();
*Wait for the thread to exit t.Join();
Console.WriteLine(“The secondary thread has terminated.”);
}
*Catch errors via exceptions..*
catch(OutOfMemoryException e) {
Console.WriteLine(“Ouch.. ran out of memory…” + e.StackTrace);
}
}
}

The “Thread = new Thread(….” line creates a new thread of execution which will start executing at the function called PrintMessage. The call to Start() in the next line actually starts the execution. The creation, execution, synchronization, and scheduling of threads is done by the runtime and is transparent to the developer.

Lastly, let us look at how error-handling is done by the runtime. In Win32, the error-handling mechanism is inconsistent. Sometimes, you deal with HRESULTs, at other times Win32 error codes and still others raise exceptions. In .Net, all the error-handling is done in a uniform manner via exceptions. This greatly simplifies writing, reading, and maintaining code. In addition, exceptions work across module and language boundaries as well. In the above program, if the code inside the try {… } block throws an exception then the runtime figures out which exception handler to execute. In this case, for out of memory exceptions, the handler is the catch{..} block right after the try block. The code inside the catch block is automatically executed once an exception is thrown, and the programmer does not have to do anything special.

We’ll discuss in future, the advanced services like security and interoperability that are provided by CLR.

Tarun Anand is technical evangelist, Microsoft India


Page(s)   1   

End of the article

PC Problems? Get a solution in 24 hours. Ask Tech Expert




Untitled Document



ZTE:Leading CDMA Technology


Extraordinary Networks:Freedom of Choice


Message boards

Discuss this and many other IT topics at the
CIOL message board

Previous Stories

Doing an MX Lookup 

Virtual Functions and Unsafe Programming

Understanding Methods

   
 

 
 

Magazine Subscription | RQS | Contact Us | Team PCQuest | Advertising - Print | jobs@cybermedia