|
|
|
What is CLR
The common language runtime is the execution engine for .NET Framework applications.
It provides a number of services, including the following:
- Code management (loading and execution)
- Application memory isolation
- Verification of type safety
- Conversion of IL to native code
- Access to metadata (enhanced type information)
- Managing memory for managed objects
- Enforcement of code access security
- Exception handling, including cross-language exceptions
- Interoperation between managed code, COM objects, and pre-existing DLLs (unmanaged code and data)
- Automation of object layout
- Support for developer services (profiling, debugging, and so on)
The following diagram will give you a high level idea about CLR
Since this article is not a full reference for CLR we will only cover four significant features provided by CLR which are
- Versioning and Deployment ("DLL Hell" is gone…)
- Memory management ("Memory leak" is gone….)
- CTS (Common Type System) and Cross Language Integration
- Metadata
Now let’s walk through each feature in detail
Versioning and Deployment (Hureeeeyy “DLL Hell” is gone…)
In the previous version of VB, managing versions of a component was quite challenging. VB developers have the ability to set the Component Version but it was not used by windows when dealing with component version (aah strange…). COM components are referred by their ProgId for example you can access excel object using Excel.Application. When you compile your application the reference to this component is stored in terms of component GUID so if your system has new version of the same component which has different GUID you might get trouble to run your application and this issue is known as “DLL Hell”.
.Net manages versioning issue more smarter way. The versioning support is provided by CLR for all component loaded in GAC (Global Application Cache). GAC is used to store shared .Net components which can be accessed by multiple applications. CLR provides three main features for versioning
- Application Isolation
- Side By Side versioning
- Automatic QFEs (Hotfixes)
Application Isolation:
In the previous version of Visual Basic whenever you create a component you must register it. So for each COM component system creates several registry entries which keep track of component path, Interfaces and associated GUIDs etc. This is extremely easy for things to go wrong. But now in .Net you can run your application which can load its own components without any registration (Kooool….) and this is made possible using rich Metadata stored in assembly. Metadata stores various useful information about assembly (i.e. Version, data types, file references etc…) and which makes it possible to find right component required by the application.
So now we are back to old DOS days when we used to store everything in INI files instead of registry and now same thing is happening again with .Net but our INI is Metadata and it’s inside the application itself… So now any .Net application can be installed just like copying a folder from one place to another place … and we call it XCOPY deployment. You can install your application by just running the command as shown below. |
Xcopy\\myserver\appdirectoryc:\progarmfiles\appdirectoryEO This command will copy all files and subdirectory from \\myserver\appdirectory to c:\progarm files\appdirectory. It will also copy the ACLs (security descriptor)
Side-By-Side Versioning:
This feature of CLR gives you an ability to store multiple versions of the same component. Take a look at the following figure and you will get more idea about this powerful feature
If .Net framework is installed on your machine then you can see all installed .Net components in GAC by browsing \Assembly path. Note the highlighted components and their versions. You can see that the highlighted components have the same name and dll name also same but you can’t see dll name in GAC explorer View. To see the dll name view properties ->Version tab and choose Internal Name. You can not see your registered component files just like regular windows file since .Net installs Shell extension to give you GAC explorer view only for Assembly folder.
You can register a new component in GAC using the following command |
Gacutil.exeimyassembley.dl To remove the assembly from GAC use /u option.
Gacutil.exe is similar to regsvr32.exe provided to register/unregister a COM component.
Automatic Quick Fix Engineering (QFE) Fixes or Hotfixes :
This is another cool feature of CLR. We know that version number can be defined in 4 part number.
CLR automatically loads highest compatible version for an application if new version is available in the GAC and this is known as Automatic QFE Fixes or Hotfixes. CLR determines highest compatible version based on Build or Revision part. If Major.Minor is same for different components then they are considered as compatible.
For example myassembley.dll (version 3.1.1.5) and myassembley.dll (version 3.1.2.5) both are considered as compatible versions by CLR because Major.Minor part is same in both assembly. In this case CLR will always load the highest compatible version (i.e. Ver 3.1.2.5).
myassembley.dll (version 3.1.1.5) and myassembley.dll (version 3.2.1.5) both are considered as in compatible versions by CLR because Major.Minor part is different in both assembly.
You can disable this Automatic QFE by modifying machine or application config file which we will discuss in the Assembly Chapter.
Memory management
Before we discuss the new Automatic Memory Management features in CLR it is very important to understand the previous version memory management scheme.
Memory leak problem in the previous version of VB
VB6 runtime also gives you automatic memory management. When object goes out of scope or its no longer referenced then VB runtime will automatically releases the memory acquired by the object. VB6 uses COM reference count method to determine when object has to be freed from memory. Reference counter is a hidden variable in each COM object. Every time a new reference is created to the Object, runtime increments the reference counter, same way when the object reference is removed runtime decrements the counter and when counter reaches to zero the memory is freed and object is removed from the application memory. Sometimes this can cause memory leak problem when you have “Circular Reference”. Circular Reference happens when Object A holds reference to Object B and Object B holds reference to Object A. In this situation Object A and Object B stays forever in memory until entire application is closed. Let’s take a look at very common example which creates memory leak because of circular reference. Remember that VB will only free object from memory when object reference counter reaches to zero or entire application is closed.
CHuman.cls |
Click here to copy the following block | Public MyParent As CHuman Public MyChild As CHuman
Private Sub Class_Terminate() MsgBox "Terminate event fired" Set MyParent = Nothing Set MyChild = Nothing End Sub |
Click here to copy the following block |
Private Sub Command1_Click() Dim oParent As New CHuman Dim oChild As New CHuman Set oParent.MyChild = oChild Set oChild.MyParent = oParent Set oParent = Nothing Set oChild = Nothing End Sub |
The above example shows you how Circular Reference can create serious memory leak problem if you have long running application. VB set objects to Nothing when you go out of scope in other word decrements the reference counter for the object but this does not guarantee that setting Object=Nothing will free it from the Application Memory coz object stays in memory until reference counter becomes zero. This type of problems can be solved by taking some caution when writing the application but believe me most of applications never written like that. What we could have done to prevent memory leak in the previous example is set all members of oParent and oChild to Nothing before we go out of scope of Command1_Click(). You can write cleaning logic (e.g. setting class member variables to Nothing) in a separate routine (e.g. Cleanup()) and call this method before setting your object to Nothing. Well now you know that how to prevent this problem but still this is manual approach even though VB has automatic memory management.
CLR Garbage Collector (GC)
The Garbage Collector is responsible for collecting objects no longer referenced by the application. This approach is quite different that VB reference count method. In reference count method object is freed when reference counter reaches zero. So object is released from memory when last reference is set to Nothing.
The GC may automatically invoked by CLR or application may explicitly call it by calling GC.Collect method. Garbage Collection approach is non deterministic so you can’t tell when object will be destroyed. Periodically GC will determine which object needs to be cleaned.
GC obtains a list of objects those are directly referenced by the application. Then for each “root” object it determines all other objects referenced directly or indirectly by the “root” object. Once this process is completed GC is ready to free all other objects not found in the elimination process. CLR executes object’s Finalize method just before GC collects the object to free the memory, you can override this method if you want to write your own clean up code, but don’t treat Finalize as VB class_terminate event. Since GC collects objects in low memory situation you can not be sure when Finalize will execute. If you need cleanup in timely fashion then you can implement your own Cleanup routine as below. Call cleanup routine from your application just before you set object to nothing. It’s a good idea to name your clenup routine Dispose() so we stay consistent with all other .Net classes who also name it Dispose(). |
CTS (Common Type System) and Cross Language Integration
Well if you have ever tried to call routines written in one language from a different language then you know that how much pain is that. Main reason is each language has its own set of datatypes and when you call those routines from different language then you have to map datatypes explicitly in the calling language. For example you can call APIs written in C from VB but before you call API you have to do some extra work. Let’s look at the example.
If you want to call CopyFile function of Kernel32.dll which is written in C then before you call the CopyFile function you must declare it in VB as shown below. In C lpExistingFileName and lpNewFileName are defined as LPTSTR but when you call it from VB we must convert it to String datatype. |
This was the one reason .Net came up with idea called CTS (Common Type System). CTS is a set of common datatypes on which all .Net languages are built. That means C#, VB.net, J#.... all uses the same set of datatypes which makes it easy to call routines written in one .net language from another .Net language. Now because of CTS you can write your class in VB.net which may be inherited from a class written in C# or J#. You can call C# method in your VB.net or J# code without any extra work. You can also debug your code seamlessly from one language to another language which was impossible before in VB6 or VC++ and this is all made possible because of CTS.
Every type Supported in CTS is derived from System.Object. Therefore every type supports the following method of System.Object class.
Equals(Object) as Boolean : Used to test equality of the passed object with current object. Reference typ should return True if the Object parameter references the same Object. Value type should return True if Object parameter has the same value.
GetHashCode as Int32 : Generates a number (called Hash) corrosponding to the value of an Object. This number is extensively used by sorting algorithm implemented in System.Collection classes.
GetType() as Type : Returns a System.Type object. This is an entry point to get many other metadata about the datatype (e.g. datatype name, supported interfaces, methods, properties etc...).
ToString() as String : Default implementation of this method returns fully qualified name of the class of the Object. Generally this method is overloaded to return most commonly used value (e.g. Integer can return String representation of the value).
Here is the list of core datatypes which also known as "Primitive Types".
- Boolean
- Byte
- Char
- DateTime
- Decimal
- Double
- Guid
- Int16
- Int32
- Int64
- Sbyte
- Single
- TimeSpan
Meta Data
Meta Data is information which describes the assembly. Meta Data is used to provide rich information like assembly version, company, classes, methods, fields etc. Meta Data is used by CLR to provide functionality like validating assembly before executing it. Side By Side Versioning, Garbage Collection and many more…
VB Programmers have used Meta Data for years while developing and using components in their application. Basically COM components store their meta data in type library which can be a separate file or it can be embedded in component’s dll/exe itself. But again not all Metadata is stored in Type Lib, some information is stored in registry and information related to COM+ is stored in COM+ catalog so it can be very problematic while updating or registering a COM/COM+ component. On the otherside .Net makes it so clear by storing all information at one location in the assembly file itself so its easier to update and since all information is stored in assembly itself no registry entries required. Meta Data is generated at compile time by Compiler and its embedded in dll/exe. Its binary information but you can extract it using Reflection APIs provided by .Net framework.
Here are some of the items in the Meta Data defined for .Net Framework.
Information about assembly - Name, Version, Culture - Public Key for verification - Types exported by the assembly - Dependencies (Other assembly on which this assembly depends on) - Security permissions to run this assembly Base classes and Interfaces Custom Attributes
Conclusion
In this article we learned about the most important piece of .Net technology which is CLR. We learned about the most important features of CLR like Versioning/Deployment, Garbage Collection, Common Type System (CTS) & Language Integration and Meta Data. We also learned the pros/cons of previous version of VB Runtime; we also learned how CLR gives you some new features and eliminates limitations which we had in the previous version of VB Runtime. |
|
|
|
Submitted By :
Nayan Patel
(Member Since : 5/26/2004 12:23:06 PM)
|
|
|
Job Description :
He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting. |
View all (893) submissions by this author
(Birth Date : 7/14/1981 ) |
|
|