Thursday, July 29, 2010

Thursday, February 11, 2010

Freeing Unmanaged Resources

The garbage collector does not know how to free unmanaged resources (such as file handles, network connections, and database connections). When defining a class, you can use two mechanisms to automate the freeing of unmanaged resources

Declaring a destructor (or finalizer) as a member of your class

Implementing the System.IDisposable interface in your class

Destructors
Destructors are called before an object is destroyed by the garbage collector. When you define a destructor in C#, what is emitted into the assembly by the compiler is actually a method called Finalize().
class MyClass
{
~MyClass()
{
// destructor implementation
}
}

The following example shows the C# code equivalent to the IL that the compiler would generate for the~MyClass destructor:

protected override void Finalize()
{
try
{
// destructor implementation
}
finally
{
base.Finalize();
}
}

C# destructors are non deterministic
When a C++ object is destroyed, its destructor runs immediately. Here it depends on GC. Another problem with C# destructors is that the implementation of a destructor delays the final removal of an object from memory.Objects that do not have a destructor get removed from memory in one pass of the garbage collector, but objects that have destructors require two passes to be destroyed:
The first one calls the destructor without removing the object, and the second actually deletes the object.

The IDisposable Interface
In C#, the recommended alternative to using a destructor is using the System.IDisposable interface
The implementation of Dispose() should explicitly free all unmanaged resources used directly by an object
Suppose you have a class named ResourceGobbler, which relies on the use of some external resource and implements IDisposable

ResourceGobbler theInstance = new ResourceGobbler();

// do your processing

theInstance.Dispose();

Unfortunately, this code fails to free the resources consumed by theInstance if an exception occurs during processing

ResourceGobbler theInstance = null;

try
{
theInstance = new ResourceGobbler();

// do your processing
}
finally
{
if (theInstance != null) theInstance.Dispose();
}

C# offers a syntax that you can use to guarantee that Dispose() will automatically be called against an object that implements
IDisposable when its reference goes out of scope
using (ResourceGobbler theInstance = new ResourceGobbler())
{
// do your processing
}

variable to be scoped
when that variable goes out of scope, its Dispose() method will be called automatically, even if an exception occurs.

Implementing IDisposable and a Destructor
The execution of a destructor is enforced by the runtime but is nondeterministic and places an unacceptable overhead on the runtime because of the way garbage collection works.
The IDisposable interface provides a mechanism that allows users of a class to control when resources are freed, but requires discipline to ensure that Dispose() is called.

Regards,
Praveen KVC
5 February 2010

Garbage Collection

The lives of the heap-based objects are not coupled to the scope of the individual stack-based variables that reference them. When the garbage collector runs, it will remove all those objects from the heap that are no longer referenced. As soon as the garbage collector has freed up all the objects it can, it compacts the heap by moving all remaining objects to form one contiguous block of memory. when the objects are moved about, all the references to those objects need to be updated with the correct new addresses, but the garbage collector handles that too.

Generally, the garbage collector runs when the .NET runtime determines that a garbage collection is required. You can force the garbage collector to run at a certain point in your code by calling System.GC.Collect().The System.GC class is a .NET class that represents the garbage collector, and the Collect() method initiates a garbage collection. The GC class is intended for rare situations in which you know that it's a good time to call the garbage collector; for example, if you have just dereferenced a large number of objects in your code. However, the logic of the garbage collector does not guarantee that all unreferenced objects will be removed from the heap in a single garbage collection pass.

Regards,
Praveen KVC
4 February 2010

Memory Management for Reference Data Types

Although the stack gives very high performance, it is not flexible enough to be used for all variables. The requirement that the lifetimes of variables must be nested is too restrictive for many purposes. Often, you will want to use a method to allocate memory to store some data and be able to keep that data available long after that method has exited. This possibility exists whenever storage space is requested with the new operator — as is the case for all reference types. That's where the managed heap comes in.

The managed heap (or heap for short) is just another area of memory from the process's available 4GB. The following code demonstrates how the heap works and how memory is allocated for reference data types:

void DoWork()
{
Customer arabel;
arabel = new Customer();
Customer mrJones = new Nevermore60Customer();
}

This code assumes the existence of two classes, Customer and Nevermore60Customer

First, you declare a Customer reference called arabel. The space for this will be allocated on the stack, but remember that this is only a reference, not an actual Customer object. The arabel reference takes up 4 bytes, enough space to hold the address at which a Customer object will be stored. (You need 4 bytes to represent a memory address as an integer value between 0 and 4GB.)

The next line

arabel = new Customer();
does several things. First, it allocates memory on the heap to store a Customer object (a real object, not just an address). Then it sets the value of the variable arabel to the address of the memory it has allocated to the new Customer object. (It also calls the appropriate Customer() constructor to initialize the fields in the class instance, but we won't worry about that here.)

The Customer instance is not placed on the stack — it is placed on the heap. In this example, you don't know precisely how many bytes a Customer object occupies, but assume for the sake of argument it is 32. These 32 bytes contain the instance fields of Customer as well as some information that .NET uses to identify and manage its class instances.

When a reference variable goes out of scope, it is removed from the stack, but the data for a referenced object is still sitting on the heap. The data will remain on the heap until either the program terminates, or the garbage collector removes it, which will only happen when it is no longer referenced by any variables.

Regards,
Praveen KVC
3 February 2010

Memory Management for Value Data Types

Windows uses a system known as virtual addressing, in which the mapping from the memory address seen by your program to the actual location in hardware memory is entirely managed by Windows. The result of this is that each process on a 32-bit processor sees 4GB of available memory, irrespective of how much hardware memory you actually have in your computer (on 64-bit processors this number will be greater). This 4GB of memory contains everything that is part of the program, including the executable code, any DLLs loaded by the code, and the contents of all variables used when the program runs. This 4GB of memory is known as the virtual address space or virtual memory. For convenience in this chapter it is referred to simply as memory.

Somewhere inside a process's virtual memory is an area known as the stack. The stack stores value data types that are not members of objects. In addition, when you call a method, the stack is used to hold a copy of any parameters passed to the method. To understand how the stack works, you need to understand the importance of variable scope in C#. It is always the case that if a variable a goes into scope before variable b, then b will go out of scope first. Look at this code:

{
int a;
// do something
{
int b;
// do something else
}
}

First, a gets declared. Then, inside the inner code block, b gets declared. Then the inner code block terminates and b goes out of scope; then a goes out of scope. So, the lifetime of b is entirely contained within the lifetime of a. The idea that you always deallocate variables in the reverse order to how you allocate them is crucial to the way the stack works.

Regards,
Praveen KVC
2 February 2010

Sunday, January 31, 2010

Virtual Methods

By declaring a base class function as virtual, you allow the function to be overridden in any derived classes:

class MyBaseClass
{
public virtual string VirtualMethod()
{
return "This method is virtual and defined in MyBaseClass";
}
}

It is also permitted to declare a property as virtual. For a virtual or overridden property, the syntax is the same as for a non-virtual property, with the exception of the keyword virtual, which is added to the definition. The syntax looks like this:

public virtual string ForeName
{
get { return fName;}
set { fName = value;}
}
private string foreName;
For simplicity, the following discussion focuses mainly on methods, but it applies equally well to properties.

The concepts behind virtual functions in C# are identical to standard OOP concepts. You can override a virtual function in a derived class, and when the method is called, the appropriate method for the type of object is invoked. In C#, functions are not virtual by default, but (aside from constructors) can be explicitly declared as virtual. This follows the C++ methodology: for performance reasons, functions are not virtual unless indicated. In Java, by contrast, all functions are virtual. C# differs from C++ syntax, however, because it requires you to declare when a derived class's function overrides another function, using the override keyword:

class MyDerivedClass : MyBaseClass
{
public override string VirtualMethod()
{
return "This method is an override defined in MyDerivedClass";
}
}

This syntax for method overriding removes potential runtime bugs that can easily occur in C++, when a method signature in a derived class unintentionally differs slightly from the base version, resulting in the method failing to override the base version. In C# this is picked up as a compile-time error, because the compiler would see a function marked as override but no base method for it to override.

Neither member fields nor static functions can be declared as virtual. The concept simply wouldn't make sense for any class member other than an instance function member.

Regards,
Praveen KVC
1 February 2010

Implementation Inheritance

If you want to declare that a class derives from another class, use the following syntax:

class MyDerivedClass : MyBaseClass
{
// functions and data members here
}

Note This syntax is very similar to C++ and Java syntax. However, C++ programmers, who will be used to the concepts of public and private inheritance, should note that C# does not support private inheritance, hence the absence of a public or private qualifier on the base class name. Supporting private inheritance would have complicated the language for very little gain. In practice, private inheritance is used extremely rarely in C++ anyway.


If a class (or a struct) also derives from interfaces, the list of base class and interfaces is separated by commas:

public class MyDerivedClass : MyBaseClass, IInterface1, IInterface2
{
// etc.

For a struct, the syntax is as follows:

public struct MyDerivedStruct : IInterface1, IInterface2
{
// etc.

If you do not specify a base class in a class definition, the C# compiler will assume that System.Object is the base class. Hence, the following two pieces of code yield the same result:

class MyClass : Object // derives from System.Object
{
// etc.
}

and

class MyClass // derives from System.Object
{
// etc.
}

For the sake of simplicity, the second form is more common.

Because C# supports the object keyword, which serves as a pseudonym for the System.Object class, you can also write:

class MyClass : object // derives from System.Object
{
// etc.
}

If you want to reference the Object class, use the object keyword, which is recognized by intelligent editors such as Visual Studio .NET and thus facilitates editing your code.

Regards,
Praveen KVC
31 January 2010