Everyone who starts their way in programming gets acquainted with the operator New and learns how it can be used to create instances of a type. However, few people think about how it does it, and what it is capable of. The work of this operator can be divided into several stages:
- Calculation (how much our object weighs)
- Allocation (memory for our object)
- Initialization (creating our object)
Letβs take a closer look at what happens when an object is created by using this operator.
Calculation
First, the number of bytes required to store all instance fields of the type is calculated, which means that it is considered how much all the elements of our instance weigh + 8/16 bytes for the SyncBlock Index & Type Object Pointer.
Example:
class MyExampleClass
{
private string _myString = "String";
}
Our class contains one field of the String type that takes 4 bytes + we add 4 bytes of synchronization block to it and add a pointer to the object type plus 2 bytes for each character that contains our string type field
StringValue = SyncBlock (4) + TypeHandle (4) + m_stringLength (4) + m_firstChar (2) + βStringβ (12) = 26 bytes.
The extra 2 bytes need for the alignment done by the CLR memory manager.
The main difference is the size of the DWORD, the memory pointer. On 32-bit systems it is 4 bytes, on 64-bit systems it is 8 bytes.
So, if an empty class is equal to only 12 bytes in x86, then in x64 it is already 24 bytes.
Selection
The memory for the object is now allocated, reserving the required number of bytes for the type in the managed heap. The allocated bytes are initialized to zero (0).
As long as there is address space available on the managed heap, the CLR continues to allocate space for new objects, but when it runs out, garbage collection is performed using an optimization mechanism, releasing objects and fragmenting them.
Initialization
Now we need to initialize the pointer to the type object and the synchronization block index and call the type instance constructor with the parameters specified when calling new.
Most compilers automatically include code for calling the base class constructor in the constructor. Each constructor initializes the fields defined in the corresponding type. In particular, the System.Object constructor is called, but it does nothing and simply returns.
Limitation
The new constraint specifies that the type argument in a generic class declaration must have a public parameterless constructor. You can use the new constraint only if the type is not abstract. When using the new() constraint with other constraints, it must be specified last.
Apply the new constraint to a type parameter when the generic class creates new instances of that type. This is shown in the following example:
public class ItemFactory2<T> where T : IComparable, new()
{
// Your code here;
}
Top comments (0)