Class (2)-Destructors and garbage collection

Source: Internet
Author: User

Once a class is defined, we can new any number of objects. At this point, the memory allocation on the managed heap and stack is generated, and the heap will open up a new space to store the class object, and the stack simply stores the reference. In general, garbage collection and memory management are only relative to the managed heap. The memory management of C # is very convenient-that is, the garbage collector will be responsible for all the work, without management at all. For garbage collection, there are several issues that need to be clarified.

What is garbage: In general, an object is considered garbage if it is inaccessible in any part of the code.

When the garbage collector works: when it deems it necessary (explained below) or the user calls.

Garbage collector ignores unmanaged resources, what to do: Write your own code release, there are two ways to finalize and Dispose

Basic concepts

The managed heap holds a pointer that indicates where the next object will be assigned, and when the system runs to the new keyword, the newobj directive is added to the CIL, which is responsible for the following:

1. Calculate the total amount of memory required for new objects to be allocated, including all of their own members and base classes

2. Check the pointer on the managed heap to determine if the managed heap has enough memory to allocate the object, and if sufficient, start the static and normal constructors and return the reference (the previous position of the pointer to the next object)

3. Move the managed heap pointer to the next available location

4. If the second step finds that there is not enough space, perform a garbage collection

Note that setting the object to null does not cause garbage collection, or clears the space on the managed heap. This simply removes the connection (reference) between the object and the managed heap, which means that the object does not point to anything on the managed heap.

Basic algorithms

When garbage collection occurs, the runtime examines the objects in the managed heap and determines whether the application can still access them. The entire garbage collection is divided into two steps.

Phase 1:mark-sweep mark the purge phase, assuming that all objects in the heap can be recycled, and then identify objects that cannot be reclaimed, mark them, and finally the objects that are not tagged in the heap can be recycled.

The garbage collector determines which objects are no longer in use by examining the root of the application when performing a collection. Simply put, the root is a storage location that holds a reference to an object on the managed heap (that is, the two arrows in the). Each application has a set of roots, which are stored in a list, each root either referencing an object in the managed heap, or set to null.

The garbage collector can access the list of active roots, check the root of the application against this list, and create a chart in the process that contains all the objects that can be accessed from those roots. Objects that are not in the diagram will not be accessible from the root of the application. The garbage collector will consider marking inaccessible objects as garbage and freeing the memory allocated for them. In, because C2 is set to null, no root points to the C2 in the managed heap, and it is considered garbage.

Phase 2:compact The compression phase, after all the garbage is marked, frees up their memory space, the memory space becomes discontinuous, and the objects are moved in the heap so that they are re-arranged from the heap base address, similar to the defragmentation of disk space.

Improvement of garbage collection algorithm-generational

When it comes to garbage collection, scanning all objects will be time-consuming, and in order to optimize the process, a generational algorithm appears. The essence of the generational algorithm is that "the longer an object exists, the more important it may be, and the more likely it should be retained ."

. NET divides the heap into 3 age zones: Gen 0, Gen 1, Gen 2;

All objects are created in the No. 0 generation. If the Gen 0 heap memory reaches the threshold, the 0-generation GC is triggered (only 0-generation objects are scanned at this time) and the surviving objects in Gen 0 after the 0-generation GC enter GEN1. If Gen 1 's memory reaches the threshold, the 1 generation gc,1 GC recycles the Gen 0 heap and Gen 1 heap, and the surviving objects enter Gen2. The 2-generation GC recycles the Gen 0 heap, Gen 1 heap, and Gen 2 heap, and Gen 0 and Gen 1 are smaller, and the two generations are always around 16M, and the size of the Gen2 is determined by the application and can reach a few g, so the cost of the 0 generation and 1 generation GC is very low, The 2-generation GC, called full GC, is usually expensive. A rough calculation of the 0 and 1 generation GC should be possible between a few milliseconds to dozens of milliseconds, and the full GC might take a few seconds to complete when Gen 2 heap is large. In general terms. NET application runs, the 2-generation, 1-generation, and 0-generation GC frequencies should be roughly 1:10:100.

With the generational algorithm, the program does not need to scan all objects.

(http://www.cnblogs.com/springyangwc/archive/2011/06/13/2080149.html)

Other

Garbage collection usually does not require manual intervention, but there are a few exceptions. Because garbage collection applies only to managed objects (more precisely to objects that can be terminated ), it is a part of the CLR that cannot be controlled or managed for unmanaged objects, such as file streams, database connections, System window handles, printer resources, and so on ... These resources typically do not exist in the heap (where memory is used to store object instances). Do not enjoy garbage collection, we still have to release memory ourselves. We have a lot of options at this point. For example, we are going to anticipate that several larger resources will be created, and the system may not have as many resources on the managed heap as we can do:

1. Forcing a call to garbage collection, clearing all useless managed objects on the managed heap

2. Use Dispose () or implement the IDisposable interface on any object to make the object disposable, and then explicitly or implicitly call Dispose () to kill the object with precision

3. Implement the Finalize () method on an unmanaged object ( only by defining a destructor ) to make the object available for finalization , and then the object can enjoy the benefits of the garbage collector's automatic cleanup

Of these, 2 and 3 can be combined, which is also standard practice.

Forced garbage Collection

Forcing garbage collection requires calling the Gc.collect method, which can force a garbage collection. This method has an overloaded version and can specify the generation of the collection. After the method is called, waitforpendingfinalizers () can be called immediately to determine that all the objects that can be finalized must perform all necessary cleanup work before the program continues execution.

Overriding the Finalize method

Actually, we can't. The Finalize method can only be done implicitly by defining a destructor, because when the compiler executes the destructor, it automatically adds a lot of code to the Finalize method that is implicitly overridden. We can add code to the destructor to clear the unmanaged resources, and even print things to the console, but the execution time of the destructor is unpredictable (at garbage collection time). After you define a destructor for an unmanaged object, it becomes final, and then we can expect the system to dispose of it in the same way as the managed object. However, this method is more passive (still waiting for garbage collection), if you want to purge proactively, implement the IDisposable interface, make the object disposable, and then explicitly or implicitly call Dispose ().

Deconstruction functions (Finalizers) and Dispose ()

(http://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html)

If our type uses unmanaged resources, or if we need to explicitly dispose of managed resources, it is best to have the type inherit the interface IDisposable. this is equivalent to telling the caller that the type is required to explicitly dispose of the resource, and you need to call my Dispose method. The call to dispose has nothing to do with garbage collection, and garbage collection does not automatically call Dispose (). So, if the user remembers the call, then no more destructors need to be called, and if the user forgets to call, the destructor needs to be cleaned up (the formal approach is to do so). In general, wrapping with a using block can make the system call Dispose itself (after leaving the using block).

Formal methods of disposal

Microsoft has defined a formal disposition model for releasing resources, noting the following issues:

1. You can call dispose more than once () without a problem (if it has already been called, calling again should not trigger the cleanup process)

2. If you call Dispose (), you do not need to call the finalizer again

3. The object is both an endpoint and an active free memory

classbaseclass:idisposable {BOOLdisposed =false; //for external invocation         Public voidDispose () {//for garbage collectionDispose (true); //notifies garbage collection that the finalizer is no longer called because we have manually freed the memoryGc. SuppressFinalize ( This); }        //Internal        protected Virtual voidDispose (BOOLdisposing) {            if(disposed)return; if(disposing) {//clean up Managed resources            }            //Cleanup of unmanaged Resources//let the type know that they have been releaseddisposed =true; }        /// <summary>        ///must, in case the programmer forgets to explicitly call the Dispose method/// </summary>~BaseClass () {//must be falseDispose (false); }    }

Where the destructor is a special function, and the name of the class is the same, before adding a wave number ~. The whole point of providing the destructor is that the caller of the type cannot be sure to invoke the Dispose method voluntarily, and the finalizer is used as a remedy for resource release, based on the feature that the destructor is called by the garbage collector.

Class (2)-Destructors and garbage collection

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.