tags:

views:

423

answers:

3

Here a lot of people is confuse,

Normal class store it's data in the heap right? And the reference(Pointer) to the stack.

When the stack fall out of scope, Next time the GC(I bet you know what it's mean this time) kicks in and removes the memory from the heap.

Now in case of static classes, the memory can't be clean by GC 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 gets it's reference from(Where does it store the reference to the static class)? Or it just call it directly but how?

+10  A: 

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 it anywhere. 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. This class will never consume memory on the heap. However, in the DoSomethingUseful method, it has two references to the ObjectWrapper on the stack. One is passed in, and one is created.

Paul Williams
+1, enjoyed the detail.
sixlettervariables
As far as "roots" go, check out this article that explains .NET's GC algorithm and clarifies how roots have a role in the GC. http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
felideon
There are several points in this answer that are not entirely accurate. For one, the statement 'There is no "reference" to it anywhere' is incorrect. 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. Also, 'This class will never consume memory on the heap' is incorrect as well...while it does not consume GC heap space, it DOES consume heap space on a loader heap. The idea of a reference simply being a pointer is also incorrect...the CLR uses many levels of indirection.
jrista
Please see the article I linked in my answer to fully understand the type system. It is not as simple as C or C++, there is more than one heap, there is more than one kind of heap, "pointers" are less common than "references", which are often indirected several times before you actually get to the "thing" the reference refers to, and the concept that a "static" class does not live on "the heap" at all is fallacious. Depending on its structure, a static class may have pieces of itself on several heaps.
jrista
Thank you for the extra info.
Paul Williams
+3  A: 

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.)

jrista
A: 

very nice reply Paul William

mush