The “override” keyword is used to hide the definition of a method in the derived class. Whereas the new keyword is used to provide a new definition for the method.
The "virtual “ keyword make the method to be overridden in the derived class.
Let us understand the difference like this. When we declare a parent object and instantiate it with the child object, and when we use this object to call overridden method then the child class method will be executed. And in case of new method the parent class method will be called.
So in case of overriding , this is called as polymorphism.
But if we have declared child object and instantiating it with the same, and then if we make a call to the method with the object then in both the cases the derived method will be invoked. Lets see this with an example.
Here we have one base class named “Base”, which has two member methods, “one()” that is marked as virtual. Other is “two()” which is a non-virtual method.
Now we have a class “Child” which is derived from the “Base”. It has overriden method “one()” and a new method “two()”.
In the Main() method we have declared “b” as Base type and instantiated it with the Child type. And “c” is declared and instantiated as “Child” type.
When one execute this piece of code, following will be the observation:
Child overridden method one
Child new method two
Child overridden method one
Base non virtual method TWO
Thus it can be seen, our point is very clearly demonstrated with this example.
July 10, 2009
Virtual, Override, New keywords in .net
.Net Portable Executable File Format
A Windows executable, EXE or DLL must conform to the PE(Portable Executable) file format which is derivative of the Microsoft’ Common Object File Format(COFF). The Windows OS knows how to load and execute DLLs and EXEs because it understands the PE format. So any compiler that wants to generate windows executables must conform to the PE format.
In Standard Windows PE files we have two sections one is PE/COFF headers that reference the contents in the PE file, while the other section holds the number of native image sections, including .data, .rdata, .rsrc and .text sections. Microsoft has added a few sections to the standard PE file to provide support to the CLR. The CLR manages and understands these new sections.
As shown in the figure above, in .net PE file we have CLR headers and CLR data section in addition to the standard ones. The CLR header indicates that it is a .net executable, while CLR data holds the metadata and the IL(Intermediate language) that determine how the program needs to be executed.
This can be proved using tool dumpbin.exe
Just run “dumpbin.exe” on the command prompt followed by the executable file name with switch /all.
e.g : dumpbin.exe test.exe /all
it will illustrate the components of the PE
July 9, 2009
Garbage Collection
MEMORY MANAGEMENT :
In .net the memory management is handled by the CLR by means of Garbage Collector automatically . it solves the developers problem of keeping track of all the references and later freeing them when they are not in use. Which is a tedious task is done manually and if not done accurately can lead to memory leaks.
The Garbage Collection Algorithm.
Note: Roots identify storage locations, which refer to the objects on the managed heap or to objects that are set to null.
This algorithm involves the two phases/steps (mark and compact).
In the mark phase , aim is to identify the memory to be claimed and mark them. As the collector starts running it starts from the root object (usually global or static object pointers) that is identified by the JIT compiler and then traverses to the object chain. It traces the objects and add to the graph.
Examples of root objects :
• Global and static object pointers
• Any local variable/parameter pointers on a thread’s stack.
• Any CPU registers containing pointers in the managed heap.
The list of the active root is maintained by the JIT compiler and CLR and is made accessible to the garbage collector.
The GC starts from the live references/roots and walk through all the objects building a graph of all the objects that are reachable. It stops to traverse the path as soon as it encounters an object that is already present in the graph. Hence, doesn’t go through the objects more then once, and prevents the infinite loops in case of circular linked lists of objects, thus handling cycles properly. Once all the roots are marked, the graph has the set of all the objects that somehow reachable, while all the other objects which are not reachable are considered as garbage.
Now comes the second phase into picture i.e, “compact” phase. Here all the live objects are moved to the bottom of the heap , leaving the contiguous free memory space. Moving the objects invalidate all pointers , so the garbage collector, modifies the application’s roots to point to the new locations. Also it takes into account those objects that hold pointers to other object and correct that.
After all the garbage has been identified, all the non-garbage has been compacted, and all the non-garbage pointers have been fixed-up, a pointer is positioned just after the last non-garbage object to indicate the position where the next object can be added.
As can be seen from the above figure , the objects B,C are not referenced by any of the roots. So they are considered as the garbage and will be compacted.
To improve the performance CLR classifies the memory heap in 3 generations . This classification is made on the basis of the fact that newly created object tend to have short life. While older the object longer it will survive. There is no predefined time for a garbage collector to run. When the memory heap reaches a threshold then only it runs to release memory from the unused / non-referenced resources.
GC Generations Fig A
When initialized the heap has no objects. All new objects added to the heap are in Generation 0, once the heap gets filled up, the GC is invoked. As most of the objects are short lived only small number will survive the first collection. Those which survive the collection are moved to the Generation 1 level. So we have compact free space in Generation 0. When the next time GC is invoked, again the new survived objects are promoted to generation 1 while the generation 1 objects are moved to the generation 2. So as the objects mature in there present generation they are promoted to the next generation with each garbage collection.
Garbage Collection Part2
GARBAGE COLLECTION FOR UNMANAGED CODE
The CLR cannot clean up database connections, window handles and file handles. So to release those resources developer has implement techniques.
For this explicit cleaning, the cleaning that is not handled by GC, we need to make use of .Net’s dispose() method. Though we can even make use of the Finalize() method. In C# it is generally used as the destructor, but it is under the control of the GC. So to clean up the unmanaged resources implement the IDisposable interface. It consists of the Dispose() method, and unlike Finalize is under developers control. A Dispose() method must contain a call to GC.SuppressFinalize() notifying the garbage collector that finalization is not needed on that object. It is recommend to use both Dispose() and Finalize() methods on the object which needs to clean up the unmanaged resource. The Finalize method will act as backup to the Dispose() , in case it is not called, thus preventing the leak of unmanaged resource.
WEAK REFERENCES:
A weak reference provides a mechanism for referencing an object with the advantage that it can be garbage collected . this concept is basically implemented by the ASP.Net caches. When the memory usage becomes too high the references are cleaned up. Can be implemented as the System.WeakReference class.
Forced Garbage Collection :
Garbage Collection can be forced by invoking GC.Collect() method of the System.GC class. In some cases it is advantageous to force the garbage collection to improve the performance. However, it should be used with at most care, since every time GC runs it suspends all current executing threads. The GC.Collect method should not be located in a place from where it can be called again and again, hence degrading the performance.
July 8, 2009
ADD INDEX TO THE GRID VIEW
Create a website “web_demo”.
On the “Default.aspx” webform drag and drop a GridView.
Add a DataSource.
Bind the data control to the datasource which may be a xml file or any other DB table/tables.
Add a column for the index field. It needs to be template field.
Suppose the header text for the template field be “Index”
Then just add in the follwing code for default.aspx for the "index" field.
Unmanaged Code
Unmanaged code is the code that is not compiled to operate under CLR.In simple terms these are the block of code that is not managed by the CLR. It can be the native C++ or C with pointers, VB, Delphi etc.. All the .net framework languages are compiled to the IL + metadata + some header info for the CLR = PE. Then this PE is handled by the CLR , which finally generates the code to the assembly language instructions.
The code which follows this process or that is handled by the CLR , only those are called as the managed code, while rest are the unmanaged ones.
So the languages that are compiled by the .net compilers and are handled by the CLR those are the managed ones. The metadata and some header info that got attached to the compiled code are responsible for keeping the managed code managed, managed by the CLR. The CLR controls the definitions and boundaries (by means of CTS and CLS) , controls memory through automatic memory management of data via garbage collector and provide CAS security among other benefits. The unmanaged code uses the unmanaged heap for memory and knows nothing about the CLR. Essentially in both the cases a PE(Portable Executable) format file is generated on compilation, difference lies in the fact that , in .Net, this PE file is called as an assembly and has IL + metadata + some header info along with the normal information. And due to these metadata and info, it is able to be JITed by the CLR to generate the native assembly language.
Also if unmanaged resource is referenced in the code, then it is the responsibility of the programmer to release that resource voluntarily when it is not in further use.
UNSAFE CODE :
In .net we have another term called “unsafe code”. In .net most of the memory management is hidden. But sometimes its essential to refer to the memory directly by means of pointers. So to make the language powerful , unsafe code was added. It basically involves the usage of pointers to refer to the memory directly.
We may need pointers to enhance performance in following applications , to name a few. But in general we don’t need to use unsafe codes in .net.
• External functions, in non-.net DLLs some functions requires a pointer as a parameter, such as Windows APIs that were written in C.
• Debugging, sometimes we need to inspect the memory contents for debugging purposes, or you might need to write an application that analyzes another application process and memory.
Pointers have their own set of advantages and disadvantages, we won’t be discussing that over here.
The keyword unsafe is used where ever we want to use pointers. lets see how we can use:
Whole class can be declared as unsafe
unsafe class classA
{
//can use pointers here.
}
some class members can also be declared as unsafe instead of the whole class.
Class classA
{
//pointer
Unsafe int *ptr;
Unsafe void myMethod()
{
//you can use pointers here
}}
Same applies to other members constructors and properties also.
To declare local variables as unsafe in a method, u need to put it in an unsafe block.
static void Main()
{
//can't use pointers here
unsafe
{//here you can declare and use pointer
}
//can't use pointers here
}
Declaring pointers
To declare a pointer of any type all what you have to do is to put ‘*’ after the type name such as
int * ptri,i;
double * ptrd;
NOTE: In C# int * ptri, i; ‘*’ applies to the type itself not the variable so ‘i’ is a pointer here, same as arrays.
Using pointers
static void Main()
{
int var1 = 5;
unsafe
{
int * ptr1, ptr2;
ptr1 = &var1;
ptr2 = ptr1;
*ptr2 = 50;
}
Console.WriteLine(var1);}
The operator ‘&’ means “address of”, so ptr1 will hold the address of var1, ptr2 = ptr1 will assign the address of var1, which ptr1 was holding, to ptr2. Using ‘*’ before the pointer name means “the contain of the address”, so 50 will be written where ptr2 points.
Now var1 value is 20.
SizeOf Operator
As the name says, sizeof operator will return the number of bytes occupied of the given data type.
unsafe
{
Console.WriteLine("sbyte: {0}", sizeof(sbyte));
Console.WriteLine("byte: {0}", sizeof(byte));
}
Output:
Sbyte:1;byte:1