Saturday 31 March 2012

Garbage Collection

About Garbage Collection
The .NET Framework's garbage collector manages the allocation and release of memory for your application. Each time you create a new object, the common language runtime allocates memory for the object from the managed heap. As long as address space is available in the managed heap, the runtime continues to allocate space for new objects. However, memory is not infinite. Eventually the garbage collector must perform a collection in order to free some memory. The garbage collector's optimizing engine determines the best time to perform a collection, based upon the allocations being made. When the garbage collector performs a collection, it checks for objects in the managed heap that are no longer being used by the application and performs the necessary operations to reclaim their memory.


Fundamentals of Memory


The following list summarizes important CLR memory concepts.
  • Each process has its own, separate virtual address space. All processes on the same computer share the same physical memory, and share the page file if there is one.
  • By default, on 32-bit computers, each process has a 2-GB user-mode virtual address space.
  • As an application developer, you work only with virtual address space and never manipulate physical memory directly. The garbage collector allocates and frees virtual memory for you on the managed heap.
    If you are writing native code, you use Win32 functions to work with the virtual address space. These functions allocate and free virtual memory for you on native heaps.
  • Virtual memory can be in three states:
    • Free. The block of memory has no references to it and is available for allocation.
    • Reserved. The block of memory is available for your use and cannot be used for any other allocation request. However, you cannot store data to this memory block until it is committed.
    • Committed. The block of memory is assigned to physical storage.
  • Virtual address space can get fragmented. This means that there are free blocks, also known as holes, in the address space. When a virtual memory allocation is requested, the virtual memory manager has to find a single free block that is large enough to satisfy that allocation request. Even if you have 2 GB of free space, the allocation that requires 2 GB will be unsuccessful unless all of that space is in a single address block.
  • You can run out of memory if you run out of virtual address space to reserve or physical space to commit.
Your page file is used even if physical memory pressure (that is, demand for physical memory) is low. The first time your physical memory pressure is high, the operating system must make room in physical memory to store data, and it backs up some of the data that is in physical memory to the page file. That data is not paged until it is needed, so it is possible to encounter paging in situations where the physical memory pressure is very low.




Garbage collection occurs when one of the following conditions is true:
  • The system has low physical memory.
  • The memory that is used by allocated objects on the managed heap surpasses an acceptable threshold. This means that a threshold of acceptable memory usage has been exceeded on the managed heap. This threshold is continuously adjusted as the process runs.
  • The GC.Collect method is called. In almost all cases, you do not have to call this method, because the garbage collector runs continuously. This method is primarily used for unique situations and testing.


    GC.Collect Method

    Use this method to try to reclaim all memory that is inaccessible.
    All objects, regardless of how long they have been in memory, are considered for collection; however, objects that are referenced in managed code are not collected. Use this method to force the system to try to reclaim the maximum amount of available memory.


    using System;
    
    namespace GCCollectExample
    {
        class MyGCCollectClass
        {
            private const int maxGarbage = 1000;
    
            static void Main()
            {
                // Put some objects in memory.
                MyGCCollectClass.MakeSomeGarbage();
                Console.WriteLine("Memory used before collection: {0}", GC.GetTotalMemory(false));
    
                // Collect all generations of memory.
                GC.Collect();
                Console.WriteLine("Memory used after full collection: {0}", GC.GetTotalMemory(true));
            }
    
            static void MakeSomeGarbage()
            {
                Version vt;
    
                for(int i = 0; i < maxGarbage; i++)
                {
                    // Create objects and release them to fill up memory
                    // with unused objects.
                    vt = new Version();
                }
            }
        }
    }
    
    


No comments:

Post a Comment