. Net GC misunderstanding
I recently interviewed some people and found that there are errors in the. NET GC (garbage collection) comprehension. GC is actually a very complex system. Although we don't need to consider it in 95% cases, we still have to deal with the GC system in 5% cases to solve the problem. For example:
Void func ()
{
A A = new ();
B = new B ();
A. reftob = B;
B. reftoa =;
}
So will a and B be recycled by GC? Several people have incorrect answers. If you think about GC in the com mode, it is totally wrong. Every time I ask "under what circumstances will the object be recycled by GC ?", They can all answer "when there is no reference to the object in the program ". But it's wrong. Why? If you still don't understand it, let's look at the above Code.
The GC management object is not in the reference counting mode of COM. In fact, Microsoft initially wanted to use the reference counting method to implement GC. One advantage of this was that the object's analysis time was fixed. When the reference counting was 0, the object would be destructed, in this case, no code can access this object. However, this method was abandoned after repeated experiments. One reason is that, in the preceding example, the object cannot be released. Another important reason is that the additional overhead of the application count is unacceptable to high-performance programs. Especially in the case of multithreading, because. net uses a free-threaded model, multiple threads may access an object at the same time, and every increase or decrease in reference count operation has to be done in thread synchronization.
. Net adopts the GC mode of generation GC (generational GC), and the heap space is divided into three generations based on the lifetime of the object. The newly allocated objects are allocated in the order of addresses in the 0th generation. When the space in the 0th generation (about several hundred K) is used up, the objects that can be referenced in the program are moved to the 1st generation, the rest is garbage, and The 0th generation space can be re-allocated. Similarly, the 1st generation runs according to the same logic, so the objects in the 2nd generation will be objects with a long lifetime. The following points can be introduced:
1) The object allocation time overhead is much smaller than the C ++ heap allocation, but the collection time overhead is greater than the allocation time overhead.
2) There will be no excessive heap fragments in C ++, which is conducive to long running of the program.
3) cyclically referenced objects can be correctly recycled.
Then, let's answer the question: "under what circumstances will the object be recycled by GC ?" The correct answer is "when there is no alive reference to the object in the program ."
Of course, the actual situation is much more complex than described above. If you are interested, consider the following:
1) Where and when will finalizer be executed? What will happen if an exception is thrown?
2) How is a large array allocated with more than 0th generations of space allocated?
3) Why does dispose () be called multiple times?