Wednesday, December 31, 2008

Microsoft Virtualization - Summary

Nice images that I copied from one of the Webcasts





1. How does licensing work for virtualization ?

To make it easy, with the DataCenter edition, you can have unlimited licenses and includes the license for the host OS.

Friday, November 7, 2008

Serialization - Advanced Topics

1. IDeserializationCallback

2. FormatterServices

3. Serializing a type that was not designed to be serializable.

4. Overriding the Assembly or Type When Deserializing an Object

http://msdn.microsoft.com/en-us/magazine/cc188950.aspx

Serialization - ISerializable

Occasionally, you will design a type that requires complete control over how it is serialized and deserialized. The type must

1. Implement


public interface ISerializable {
void GetObjectData(SerializationInfo, StreamingContext context);
}


The GetObjectData method is responsible for determining what information is necessary to serialize the object and adds this information to the SerializationInfo object. The formatter now takes all of the values added to the SerializationInfo object and serializes each of them to the byte stream.

There are many destinations for a serialized set of objects: same process, different process on the same machine, different process on a different machine, and so on. In some rare situations, an object might want to know where it is going to be deserialized so that it can emit its state differently.

A method that receives a StreamingContext structure can examine the State property's bit flags to determine the source or destination of the objects being serialized/deserialized.

Note : Always call an overloaded AddValue methods to add serialization information for your type. If a field's type implements the ISerializable interface, don't call the GetObjectData on the field.

2. A constructor

If your class is sealed, I highly recommend that you declare this special constructor to be private.


protected Hashtable(
SerializationInfo info, StreamingContext context) {
}


Note: Instead of calling the various Get methods, the special constructor could instead call GetEnumerator, which returns a SerializationInfoEnumerator object that iterates through all the values contained within the SerializationInfo object. Each value enumerated is a System.Runtime.Serialization.SerializationEntry object.

A type may include fields that refer to other objects. When the special constructor is called, any fields that refer to other objects are guaranteed to be set correctly. That is, the fields' values will contain references to allocated objects. As these referenced objects may not have had their fields initialized yet, you should not execute any code in the special constructor that accesses any members on a referenced object.

If your type must access members (such as call methods) on a referenced type, then it is recommended that your type also implement the IDeserializationCallback interface's OnDeserialization method. When this method is called, all objects have had their fields set. But there's no way to tell what order multiple objects have their OnDeserialization method called. So, while the fields may be initialized, you still don't know if a referenced object is completely deserialized if that referenced object also implements the IDeserializationCallback interface.


Case 1 : Base class implements ISerializable

If your type also implements ISerializable, then your implementation of GetObjectData and your implementation of the special constructor must call the same functions in the base class in order for the object to be serialized and deserialized properly.

If your derived type doesn't have any additional fields and therefore has no special serialization/deserialization needs, then you do not have to implement ISerializable at all. Like all interface members, GetObjectData is virtual and will be called to properly serialize the object. In addition, the formatter treats the special constructor as "virtualized." That is, during deserialization, the formatter will check the type that it is trying to instantiate. If that type doesn't offer the special constructor, then the formatter will scan all of the base classes until it finds one that implements the special constructor.

Case 2 : Base class does not implement ISerializable

In this case, your class must manually serialize the base type's fields.



void ISerializable.GetObjectData(
SerializationInfo info, StreamingContext context) {

// Serialize the desired values for this class
info.AddValue("title", title);

// Get the set of serializable members for our class and base classes
Type thisType = this.GetType();
MemberInfo[] mi =
FormatterServices.GetSerializableMembers(thisType, context);

// Serialize the base class's fields to the info object
for (Int32 i = 0 ; i < mi.Length; i++) {
// Don't serialize fields for this class
if (mi[i].DeclaringType == thisType) continue;
info.AddValue(mi[i].Name, ((FieldInfo) mi[i]).GetValue(this));
}
}


Summary of http://msdn.microsoft.com/en-us/magazine/cc301767.aspx

Serialization - Basics

Serialization is the process of converting an object or a con-nected graph of objects into a contiguous stream of bytes. Deserialization is the process of converting a contiguous stream of bytes back into its graph of connected objects. The ability to convert objects to and from a byte stream is an incredibly useful mechanism.

Formatters

Formatters know how to serialize the complete object graph by referring to the metadata that describes each object's type. The Serialize method uses reflection to see what instance fields are in each object's type as it is serialized. If any of these fields refer to other objects, then the formatter's Serialize method knows to serialize these objects, too.

Formatters have very intelligent algorithms. They know to serialize each object in the graph out to the stream no more than once. That is, if two objects in the graph refer to each other, then the formatter detects this, serializes each object just once, and avoids entering into an infinite loop.

1. Binary formatter
2. Soap formatter

Serialization Steps

1. The developer must apply the System.SerializableAttribute custom attribute to this type he wants to serialize.

2. When serializing an object, the full name of the type and the name of the type's defining assembly are written to the byte stream. By default, the BinaryFormatter and SoapFormatter types output the assembly's full identity. However, you can make these formatters write the simple assembly name (just file name; no version, culture, or public key information) for each serialized type by setting the formatter's AssemblyFormat property to FormatterAssemblyStyle.Simple.

3. When serializing a graph of objects, some of the object's types may be serializable while some of the objects may not be serializable. For performance reasons, formatters do not verify that all of the objects in the graph are serializable before serializing the graph. So, when serializing an object graph, it is entirely possible that some objects may be serialized to the byte stream before the SerializationException is thrown. If this happens, the byte stream is corrupt.

Your application code should try to recover gracefully from this situation. If you think you may be serializing an object graph where some objects may not be serializable, I recommend that you serialize the objects into a MemoryStream first. Then, if all objects are successfully serialized, you can copy the bytes in the MemoryStream to whatever stream (file or network, for example) you really want the bytes written to.

4. When you apply the SerializableAttribute custom attribute to a type, all instance fields (public, private, protected, and so on) are serialized.



Deserialization Steps

1. When deserializing an object, the formatter first grabs the assembly identity and ensures that the assembly is loaded into the executing AppDomain.

Calls Assembly class's Load or LoadWithPartialName methods.

2. After an assembly has been loaded, the formatter looks in the assembly for a type matching that of the object being deserialized. If the assembly doesn't contain a matching type, an exception is thrown and no more objects can be deserialized.

3. If a matching type is found, an instance of the type is created and its fields are initialized from the values contained in the byte stream.

4. If you use Assembly.LoadFrom to load an assembly and then construct objects from types defined in the loaded assembly. These objects can be serialized to a stream without any trouble. However, when deserializing this stream, the formatter attempts to load the assembly by calling Assembly's Load or LoadWithPartialName method instead of calling the LoadFrom method.

You implement a method whose signature matches the System.ResolveEventHandler delegate and register this method with System.AppDomain's AssemblyResolve event just before calling a formatter's Deserialize method. (Unregister this method with the event after Deserialize returns.) Now, whenever the formatter fails to load an assembly, the CLR calls your ResolveEventHandler method. The identity of the assembly that failed to load is passed to this method. The method can extract the assembly file name from the assembly's identity and use this name to construct the path where the application knows the assembly file can be found. Then, the method can call Assembly.LoadFrom to load the assembly and return the resulting Assembly reference back from the ResolveEventHandler method.

Summary of http://msdn.microsoft.com/en-us/magazine/cc301761.aspx

Saturday, November 1, 2008

c# Tips

1. as and is operator

if (o is Employee)
{
Employee e = (Employee) o;
}

In this code, the CLR is actually checking the object's type twice: The is operator first checks to see if o is compatible with the Employee type. If it is, inside the if statement, the CLR again verifies that o refers to an Employee when performing the cast.

C# offers a way to simplify this code and improve its performance by providing an as operator:

Employee e = o as Employee;
if (e != null) {
// Use e within the 'if' statement.
}

2. What should one use string or String ?

Because in C# the string (a keyword) maps exactly to System.String (an FCL type), there is no difference and either can be used.

object and string are also primitive types.

3. Type casting

C# allows implicit casts if the conversion is "safe," that is, no loss of data is possible, such as converting an Int32 to an Int64. But C# requires explicit casts if the conversion is potentially unsafe.

4. Checked and Unchecked Primitive Type Operations

a. CLR offers IL instructions that allow the compiler to choose the desired behavior. The CLR has an instruction called add that adds two values together. The
add instruction performs no overflow checking. The CLR also has an instruction called add.ovf that also adds two values together. However, add.ovf throws a System.OverflowException if an overflow occurs.

b. C# allows the programmer to decide how overflows should be handled. By default, overflow checking is turned off. As a result, the code runs faster—but developers must be assured that overflows won't occur or that their code is designed to anticipate these overflows.

One way to get the C# compiler to control overflows is to use the /checked+ compiler switch. The code executes more slowly because the CLR is checking these operations to determine whether an overflow will occur.

c. There are also checked/unchecked operators/statements.

Byte b = 100;
b = checked((Byte) (b + 200)); // OverflowException is thrown

d. Here's the best way to go about using checked and unchecked:

i. As you write your code, explicitly use checked around blocks where an unwanted overflow might occur due to invalid input data, such as processing a request with data supplied from an end user or a client machine.

ii. As you write your code, explicitly use unchecked around blocks where an overflow is OK, such as calculating a checksum.

iii. For any code that doesn't use checked or unchecked, the assumption is that you do want an exception to occur on overflow.

Now, as you develop your application, turn on the compiler's /checked+ switch for debug builds. Your application will run more slowly because the system will be checking for overflows on any code that you didn't explicitly mark as checked or unchecked. If an exception occurs, you'll easily detect it and be able to fix the bug in your code. For the release build of your application, use the compiler's /checked- switch so that the code runs faster and exceptions won't be generated.

5. Value types and reference types

a. Value type instances are usually allocated on a thread's stack (although they can also be embedded in a reference type object).

b. Reference types are always allocated from the managed heap.

c. Value type are sealed.

d. Value type can implement interfaces.

e. Value types have two representations - boxed and unboxed.

f. Value types can't be assigned null.

g. When you assign a value type variable to another value type variable, a field-by-field copy is made.

h. C# compiler selects LayoutKind.Auto for reference types (classes) and LayoutKind.Sequential for value types (structures). However, if you're creating a value type that has nothing to do with interoperability with unmanaged code, you probably want to override the C# compiler's default.

i. The StructLayoutAttribute also allows you to explicitly indicate the offset of each field by passing LayoutKind.Explicit to its constructor. Then you apply an instance of the System.Runtime.InteropServices.FieldOffsetAttribute. This allows you to create unions in C#.

Saturday, October 11, 2008

Memory Allocation - Generation GC

Since it is generational GC, in the marking phase it does not go through the entire heap.

It makes the following assumptions

1. The newer an object is, the shorter its lifetime will be.
2. The older an object is, the longer its lifetime will be.
3. Collecting a portion of the heap is faster than collecting the whole heap.

The picture shows how it works. A few things to remember

1. Generation 0 is empty immediately after a garbage collection and is where
new objects will be allocated.

2. Any objects that were in generation 0 that survived the garbage collection would be now in generation 1 and so on.

3. The objects in a generation are examined only when generation reaches its budget, which usually requires several garbage collections of generation 0. When the CLR initializes, it selects budgets for all three generations. The budget for generation 0 is about 256 KB, and the budget for generation 1 is about 2 MB. The budget for generation 2 is around 10 MB.

4. The larger the budget, the less frequently a garbage collection will occur.

5. The managed heap supports only three generations: generation 0, generation 1, and generation 2; there is no generation 3.

6. Garbage collector dynamically modifies generation 0's budget after every collection.

Memory Allocation - Details of Garbage Collection

Every type identifies some resource available for the program to use. The steps to allocate memory to resource are

1. Allocate memory for that type by calling the the new operator.

2. Initialize the memory to set the initial state of the resource and to make the resource usable. The type's instance constructor is responsible for setting this initial state.

3. Use the resource by accessing the type's members (repeating as necessary).

4. Tear down the state of a resource to clean up.

5. Free the memory. The garbage collector is solely responsible for this step.

But the garbage collector knows nothing about the resource represented by the type in memory, which means that a garbage collector can't know how to perform Step 4 in the preceding list. So how is step 4 performed... The developer writes this code in the Finalize, Dispose, and Close methods.

Step 4 can be skipped for managed resources for example String. But for a type that wraps a native resource such as a file, a database connection, a socket, a mutex, a bitmap, an icon, and so on, always requires the execution of some cleanup code when the object is about to have its memory reclaimed.

Garbage collection algorithm

1. Marking phase

The garbage collector marks all of the reachable objects.

2. Compaction phase

The garbage collector compacts the memory, squeezing out the holes left by the
unreachable objects.

But the GC is a generational collector. So in the marking phase, instead of marking the whole heap it just focusses on generation (or a portion of heap).

Finalization - Releasing Native Resources

Any type that wraps a native resource, such as a file, network connection, socket, mutex, or other type, must support finalization. Basically, the type implements a method named Finalize. When the garbage collector determines that an object is garbage, it calls the object's Finalize method (if it exists).

When an application creates a new object, the new operator allocates the memory from the heap. If the object's type defines a Finalize method, a pointer to the object is placed on the finalization list just before the type's instance constructor is called. The finalization list is an internal data structure controlled by the garbage collector. Each entry in the list points to an object that should be finalised.



A. First Pass

When a garbage collection occurs, objects B, E, G, H, I, and J are determined to be garbage. The garbage collector scans the finalization list looking for pointers to these objects. When a pointer is found, the pointer is removed from the finalization list and appended to the freachable queue which is another of the garbage collector's internal data structures. Each pointer in the freachable queue identifies an object that is ready to have its Finalize method called. After the collection, the managed heap looks like



A special high-priority CLR thread is dedicated to calling Finalize methods. Because of the way this thread works, you shouldn't execute any code in a Finalize method that makes any assumptions about the thread that's executing the code. So if an object is in the freachable queue, the object is reachable and is not garbage. Then when the garbage collector moves an object's reference from the finalization list to the freachable queue, the object is no longer considered garbage and its memory can't be reclaimed.

B. Second Pass

The next time the garbage collector is invoked, it will see that the finalized objects are truly garbage because the application's roots don't point to it and the freachable queue no longer points to it either. The memory for the object is simply reclaimed.



Questions

1. Why can't C# support destructors ?

The CLR doesn't support deterministic destruction, which makes it difficult for C# to
provide this mechanism.