Thursday, April 12, 2007

Static Classes vs Instance Classes

"Whenever a process is loaded in the RAM, we can say that the memory is roughly divided into three areas (within that process): Stack, Heap, and Static (which, in .NET, is actually a special area inside Heap only known as High Frequency Heap)."
Knowing that statics are allocated on the High Frequency Heap is actually pretty critical to answering your question. The overall answer is yes, ultimately, static classes (or static elements in a class) will perform better than instance classes (and elements within an instance of a class). Why?
Like I mentioned before, static classes are still JITted and constructed, just like any other normal class. The JIT part happens when you first use a method or access a static property/field of a static class. This is a common hit applicable to all classes in a .NET app. After JITting is complete, the class will be constructed (assuming there is construction to perform...in this area, I'm not actually sure if a .cctor is created for a static class that does not have any static fields...I'll have to check it out). When a static class is constructed, its member data is stored in the High Frequency Heap, which is actually not a garbage-collected heap (or object heap)...its whats called a Loader Heap. Loader heaps are managed differently than an object heap because they are much more predictable, and don't need nearly as much overhead as an object heap. In addition to storing values of static fields from a static class, the High Frequency Heap also stores the MethodTables, MethodDescs, and FieldDescs of the static class, which are part of the CLR type system.
In the event that you just have a static class with no member fields, an "instance" of that static class still must be compiled (JITted), and loaded (MethodTables, MethodDescs placed in HFH), and in the event that the original 32k reserve size of the High Frequency Heap is used up (possible in very large applications, and probably with very large volumes of static classes), the heap will need to be resized when this creation happens. Looking up a method when its called should take the same amount of time that it takes to look up a method on an instance of a class, since all type information (MethodTables, MethodDescs, FieldDescs, and Interface Maps) for all types, static or otherwise, are keept in the High Frequency Heap.
Now, with all that said, static classes are still going to be "lighter" than an instance class. Why? Because instance classes are allocated on the object heap (the GC heap), and any time an instance class becomes unreachable, it will be garbage collected. This garbage collection will affect the performance of an application whenever it runs. So, as you mentioned in your article, proper use of static classes can help improve the performance of an application a bit. Its just that static classes arn't "free" from a performance standpoint...they still incurr some costs, and since static classes arn't constructed until used (assuming there are static member fields), the cost of JITting, loading types, and loading static fields into the HFH happens the first time that static class is used.
If you want all the nitty-gritty low-level details, take a look at this article: http://msdn.microsoft.com/msdnmag/issues/05/05/JITCompiler/
It should answer any questions you have about the managed runtime and how it handles memory.

No comments: