Memory allocation – static class

When we create an instance of a normal class, the memory of that instance lives on the heap.

A reference to this instance might be in :

  1. An object on the heap.
    • If we set a member variable inside a different instance of an object to it.
  2. A stack variable
    • If we declared a variable to the object inside a method or passed it to a function call.
  3. It may be in the list of global roots,
  4. for static reference.

Static classes are not instantiated but are “stored” on what is called a Loader Heap. Its methods are just functions loaded into memory when the CLR loads the assembly. Static classes are guaranteed to be loaded and to have their fields initialized and their static constructor called before the class is referenced for the first time in your program. Once created a static class remains in memory until your application domain is shut down.

Loader heaps are special, non-GC heaps that have extremely predictable and strict growth rates.  A reference to every type, static or otherwise, is held on a loader heap. The entire type system is managed on a loader heap, with references to types and their members.

When a .NET application starts, several AppDomains are actually created. In addition to the primary app domain, there are system and shared app domains that contain the system namespaces and mscorelib, special heaps (such as the loader heaps), and the CLR itself.

For a fully detailed explanation, read the following MSDN Magazine article:
Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects

Difference between a static class and a singleton pattern – Interview Question

This is one of the favorite questions asked by interviewers.

I thought of putting my opinions on this topic.

  1. Most important singletons can be handled polymorphically without forcing their users to assume that there is only one instance.
  2. Singletons can implement interfaces (or derive from useful base classes).
  3. Singleton class follow the object oriented principles but not static class.
  4. A singleton can be initialized lazily or asynchronously while a static class is generally initialized when it is first loaded, leading to potential class loader issues.

My rule for choosing between static and singleton:

If there are bunch of functions should be kept together, then static is the choice.
Anything else which needs single access to some resources, could be implemented singleton.

Assembly InsideOut – Part 2 – NetModule

This post is in continuation to my previous post

In this post we will look how to create multifile  assembly. This brings us to the concept of NetModule.

Netmodule is a unit of compilation.  A compiler may give the option to compile a collection of source files into an assembly, or a netmodule. Netmodule contains type metadata and compiled code. It does not contain an assembly manifest.

A netmodule can not be deployed alone. It has to be linked into an assembly. This can be done by using compiler’s /addmodule switch (if the compiler supports it), al.exe, or in .Net framework 2.0, link.exe. After linking, the netmodule can be deployed with the assembly. The .Net framework 2.0 link.exe can produce a single file assembly, while all the other approaches produce multi-file assemblies.

I recommend reading this article for further more information.

Process of creating multi-file assembly:

Let’s use the MSDN sample as an example.

C:\ stringer.vb

' Assembly building example in the .NET Framework SDK.
Imports System
Namespace myStringer
 Public Class Stringer
   Public Sub StringerMethod()
     Console.WriteLine("This is a line from StringerMethod.")
   End Sub
 End Class
End Namespace

C:\client.cs

using System;
using myStringer; //The namespace created in Stringer.netmodule.
class MainClientApp
{
  // Static method Main is the entry point method.
  public static void Main()
  {
    Stringer myStringInstance = new Stringer();
    Console.WriteLine("Client code executes");
    //myStringComp.Stringer();
    myStringInstance.StringerMethod();
  }
}

C:\ >vbc /t:module C:\Stringer.vb

Microsoft (R) Visual Basic .NET Compiler version 8.0.40607.16
for Microsoft (R) .NET Framework version 2.0.40607.16
Copyright (C) Microsoft Corporation 1987-2003. All rights reserved.

C:\ >csc /addmodule:Stringer.netmodule /t:module C:\Client.cs

Microsoft (R) Visual C# .NET Compiler version 8.00.40607.16
for Microsoft (R) Windows (R) .NET Framework version 2.0.40607
Copyright (C) Microsoft Corporation 2001-2003. All rights reserved.
 

C:\> al c:\stringer.netmodule c:\client.netmodule /main:MainClientApp.Main /out:c:\main.exe /target:exe

Microsoft (R) Assembly Linker version 10.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.
 

Manifest of created assembly,  Blue statements shows linked modules:

// Metadata version: v4.0.30319
.module extern client.netmodule
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly extern Microsoft.VisualBasic
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_….:
.ver 10:0:0:0
}
.assembly main
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ….T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.file stringer.netmodule
.hash = (FD 0C A9 48 5D 21 80 69 7E DB EF 48 77 69 C7 A0 // …H]!.i~..Hwi..
E4 81 DD 50 ) // …P
.file client.netmodule
.hash = (FA D3 E6 75 57 7D F7 11 B8 0D B2 0D 75 32 2A BD // …uW}……u2*.
20 01 41 0D ) // .A.
.class extern public myStringer.Stringer
{
.file stringer.netmodule
.class 0x02000002
}
.module main.exe
// MVID: {2C26C760-9259-4860-A2E3-3B92C68F3882}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x03300000

What is CLI and CLR ?

CLI  (Common Language Infrastructure) 

  • CLI is a specification defined by European Computer Manufacturers Association (ECMA).
  • This specification is for a virtual machine environment that enables applications written in diverse high-level programming languages to be executed in different system environments without changing or recompiling the original source code.
  • CLI also defines a common set of data types called the Common Type System (CTS) that should be used for programs written in any programming language targeting a CLI implementation.

So, CLI specifies a standard intermediate language for the virtual machine to which the high-level language source code is compiled.

CLR (Common Language Runtime) 

  • The CLR is a standardized environment for the execution of programs written in a wide range of high-level languages including Visual Basic, C#, and C++.
  • The specification of the CLR is now embodied in the European Computer Manufacturers Association (ECMA) standard for the Common Language Infrastructure (CLI), ECMA-335, and also in the equivalent ISO standard, ISO/IEC 23271.
  • So, The CLR is just one implementation of the CLI specification that executes under Microsoft Windows on a PC.
  • With the .NET Framework, intermediate language (defined by CLI) is referred to as Microsoft Intermediate Language (MSIL). Code in the intermediate language is ultimately mapped to machine code by a just-in-time (JIT) compiler when you execute a program.

Finally, 

The CLI is a standard specification; the CLR is Microsoft’s implementation of the CLI.
Code written in the CLI intermediate language can be executed within any other environment that has a CLI implementation.