.NET components aren’t allocated off the raw memory maintained by the underlying operating system. Instead, in each physical process that hosts .NET, the .NET runtime pre-allocates a special heap called the managed heap. This heap is used like traditional operating system heaps: to allocate memory for objects and data storage. Every time a .NET developer uses the
new operator on a class:
MyClass obj = new MyClass();
The managed heap is just a long strip of memory. .NET maintains a pointer to the next available address in the managed heap. When .NET is asked to create a new object, it allocates the required space for the object and advances the pointer, as you can see in Figure 4-1. (Figure 4-1 is adapted with permission from Figure 1 in “Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework,” by Jeffrey Richter (MSDN Magazine, November 2000.)
This allocation method is orders of magnitude faster than raw memory allocation. In unmanaged environments such as C++, objects are allocated off the native operating system heap. The operating system manages its memory by using a linked list of available blocks of memory. Each time the operating system has to allocate memory, it traverses that list looking for a big enough block. After a while, the memory can get fragmented, and consequently the list of available blocks gets very long. Memory fragmentation is a major source of performance problems because of the time it takes to traverse the list for allocation requests, combined with added memory page faults and disk access penalties.