Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where does CLR store static classes?

Tags:

.net

clr

Here a lot of people are confused,

Normal class stores its data in the heap right? And the reference (Pointer) to the stack.

When the stack fall out of scope, Next time the garbage collector kicks in and removes the memory from the heap.

Now in case of static classes, the memory can't be clean by the garbage collector because it needs to be there the whole program. And there is no way of getting the reference in the first place.

So when we call Console. Write, for example? Where does the program get its reference from(Where does it store the reference to the static class)? Or it just calls it directly, but how?

like image 438
Athiwat Chunlakhan Avatar asked Aug 24 '09 19:08

Athiwat Chunlakhan


2 Answers

I think you are confusing classes with where the memory lives with how the memory is held on to. When you create an instance of a normal class, the memory of that instance lives on the heap. A reference to this instance might be in an object on the heap (if you set a member variable inside a different instance of an object to it); or a stack variable (if you declared a variable to the object inside a method or passed it to a function call), or it may be in the list of global roots (if it is a static reference, for example a Singleton reference).

A static class cannot be instantiated. There is no "reference" to the class anywhere (except for type information). Its methods are just functions loaded into memory when the CLR loads the assembly. You could create a delegate that points to one of these methods, but that doesn't make a reference to an instance the class, either. That's just a pointer to a function.

For example, look at this code:

class ObjectWrapper
{
    Object obj = new Object();
}

static void Main(string[] args)
{
    ObjectWrapper wrapper = new ObjectWrapper();
    ...
}

The Main method creates an instance of an ObjectWrapper class. This instance lives on the heap.

Inside the ObjectWrapper instance, there is an instance of class Object that lives on the heap. The reference to this class is inside the instance, so I guess you could think of the reference as "living in the heap".

Now, compare this to the following code:

class Singleton
{
    static readonly instance = new Singleton();
}

The instance of the Singleton object lives on the heap, too. However, the reference is a static reference. It is maintained by the CLR in a list of global or "root" references.

Now look at this static class:

class ObjectWrapper
{
    Object obj = new Object();
}

static class HelperMethods
{
    static int DoSomethingUseful(ObjectWrapper wrapper1)
    {
        ObjectWraper wrapper2 = wrapper1;
        // code here
    }
}

HelperMethods is a static class. You cannot instantiate the HelperMethods class. There cannot be any objects from this class on the heap. However, in the DoSomethingUseful method, it has two references to an instance of the ObjectWrapper class on the stack. One is passed in, and one is declared inside the method.

like image 118
Paul Williams Avatar answered Oct 23 '22 04:10

Paul Williams


To give you a simple answer, static classes are "stored" on what is called a Loader Heap. Loader heaps are special, non-GC heals that have extremely predictable and strict growth rates. 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

Despite being from a few years ago, it still applies. (However, I can't say if .NET 4.0 has changed this much.)

like image 24
jrista Avatar answered Oct 23 '22 03:10

jrista