
Exploring Different Stages of Memory Management in .NETMemory Lifecycle of a .NET application will fit into three stages of memory management which are dealt in detail in this article. Stage 1: Initial Memory Allocation When you declare any object or any primitive type, memory has to be initially allocated to it. Memory allocation can be categorized into three different types: Static
Memory Allocation
.NET uses
last two modes of memory allocation. Your .NET application will have memory
allocated in both stack and heap. All primitive types excluding String
are allocated in stack. To generalize it further, if your object is of
type ValueType or any of its derivatives and the object is not boxed,
then it is stored in stack. All other data structures that cannot fit
into stack memory are allocated in heap memory where in object allocation
and deallocation is done in a random way. Stage 2:
Memory Utilization Memory utilization
means that the memory that is no longer in use has to be reused. Memory
utilization can happen in two different ways: Simple:
When the memory your program requires is readily available as one continuous
block, then the memory utilization is simple Complex:
When the memory your program requires is not available in continuous block
but it is available as small memory blocks in different memory areas,
then compaction has to happen and after that memory has to be allocated.
In this case, memory utilization becomes complex Stage 3:
Compaction and Reuse In stack
based memory allocation, memory is allocated in First In First Out
basis. The allocations happen in an orderly way, ie. memory is allocated
to the primitive types at the method start and are deallocated at the
end of the method. The corresponding memory is removed from the top of
the stack and not in between. So there is no chance of fragmentation and
hence compaction is not required. In heap based
memory allocation, both stage 2 and stage 3 has complexities. Since objects
are released in random order, different blocks of memory will be available
in bits and pieces. For example if your object requires 24 bytes, heap
memory has those bytes but not in one continuous area. Then what
will happen? Since there is no continuous block of storage available,
the object cannot be allocated in memory and OutOfMemoryException will
occur. This is known as Fragmentation. These freed non-continuous blocks
have to be assembled together as one large block so that memory utilization
is simple. This is achieved using Compaction. Garbage collector
has reference counter to determine the objects that are no longer in use
and then the memory allocated to the object is freed. Garbage collector
has yet another component called compaction engine which takes care of
compaction. Consider the example mentioned earlier, if a new object requires
24 bytes that are available in the memory but not continuously, as shown
below: In the above
diagram, each block represents 8 bytes of memory. Here, the first two
blocks are free and last block is free. If they are all available together
then the object requiring 24 bytes can be allocated. Compaction engine
solves the problem and the memory area will now look like: Now the new
object can be easily allocated. However occurrence of fragmentation and
then performing compaction is a performance concern and its an expensive
task. You can avoid it with the help of an optimization technique called
Object Pooling which aims at reusing objects rather than allocating and
deallocating them frequently.
_______________________________________________________________________
FREE
Subscription
Subscribe
to our mailing list and receive new articles Note
: We never rent, trade, or sell my email lists to Visit
.NET Programming Tutorial Homepage ______________________________________________________ |