Does it collect garbage right after GC.Collect ()?

The question is for research purposes only.

I read a lot of books about C #, and this question always comes to my mind. I realized that C # is managed code, and all garbage collection happens when the CLR decides when to start garbage collection. Let it begin.

Suppose I have a simple Student class:

 public class Student { public int IdStudent { get; set; } public string Name { get; set; } public string Surname { get; set; } } class Program { static void Main(string[] args) { This is row1: Person person = new Person() {IdPerson=1, Name="Bill", SurName="Collins"}; This is row2: System.GC.Collect(); This is row3: string str="Hello World!"; } } 

Please approve or reject my suggestions:

  • Am I right that garbage collection does not start right away in row2 ?
  • GC.Collect() is just a request to do a garbage collection that DOESN'T PASS IMMEDIATELY on line2. This line can be executed in x milliseconds / seconds. In my opinion, the System.GC.Collect(); method System.GC.Collect(); just tells the garbage collector that the garbage collector should start garbage collection, but the real garbage collection can happen in x milliseconds / sec

  • Only the garbage collector knows when garbage collection will start. And if there is free space in Generation 0, garbage collection will not occur on line2: row2: System.GC.Collect();

  • It is not possible to start garbage collection right away, because we are programming in a managed environment, and only the CLR decides when to start garbage collection. Garbage collection may start in milliseconds / second or garbage collection may not start because in generation 0 there is enough space to create new objects after calling the GC.Collect() method. What a programmer can do is simply ask the CLR to start garbage collection using the GC.Collect() method.

Update:

I read this msdn article about GC.Collect Method () . . However, it is not clear to me when the real cleaning of unbound objects will begin. MSDN says:

GC.Collect Method () makes it immediately collect garbage of all generations.

However, in Notes, I read this one:

Use this method to try to recover all inaccessible memory. This blocks all generations of garbage collection.

  1. I am confused by this "Use this method for TRY" , and I think that garbage collection may not happen because the CLR decides that there is enough space for creating new objects. I'm right?
+5
source share
2 answers

SHORT ANSWER

Calling GC.Collect() will complete the garbage collection and wait for it to complete, but it will NOT wait for the pending finalizers to complete.

LONG RESPONSE

You are partially correct in your assumptions, because the GC runs in one or more background threads to run finalizers. (But see the footnote at the end of this answer.)

However, you can wait for the GC to complete by calling GC.WaitForFullGCComplete() and GC.WaitForPendingFinalizers() after calling GC.Collect() :

 GC.Collect(); GC.WaitForPendingFinalizers(); GC.WaitForFullGCComplete(); 

However, keep in mind that the thread on which the finalizers are running is not specified, so there is no guarantee that this method will complete.

Note that you should not use the GC in this way; I assume that you have a special case that you need to address, or you are doing this for research purposes.

The only acceptable case that I saw for this is when the application closes and you want to (try) to make sure that all finalizers are running, because, for example, they will clear the log files, etc.

As noted above, this still does not guarantee that all finalizers are running; it's just the best you can do.

In response to your point (5):

The documentation for GC.Collect () states:

It makes you immediately collect garbage of all generations.

So it will force the GC.

The documentation also states:

Use this method to try to recover all inaccessible memory.

The use of the word โ€œtryโ€ simply means that even if a full GC is running, not all inaccessible memory will be fixed. There are several reasons that may arise, for example, a finalizer may block.

Footnote

.Net 4.5 allows you to specify whether GC.Collect() will be blocked or not .

In fact, the documentation for GC.Collect() states that it collects garbage from all generations, which seems to contradict my statements above. However, there seems to be some confusion as to whether this is true.

See for example this thread .

The answer is: GC.Collect() will by default wait for all generations to be GCed, but will not wait for pending finalizers, which are always executed in a separate thread.

Therefore, if you do not need to wait for finalizers, you only need to call GC.Collect() , and you do not need to wait for anything else.

+4
source

There are two GCs and from your code, I believe that you want to know about the GC workstation. What minimizes pauses while working during complete collections? The workstation GC uses a second processor to run the collection at the same time, minimizing latency while reducing throughput. We need only worry about the behavior of the GC if the GC server is not doing its job properly. If you add GC.collect () to your code according to the GC of the workstation, it may be useless on the GC server.

The GC server is designed for maximum throughput and scales with very high performance. Memory fragmentation on servers is a much more serious problem than on workstations, which makes garbage collection an attractive proposition. In a uniprocessor scenario, both collectors work the same way: workstation mode, without simultaneous collection

I am confused by this. Use this method for TRY, and I think that garbage collection may not happen because the CLR decides that there is enough space to create new objects. I'm right?

For the GC workstation, GC.Collect will start collecting as soon as possible, you can safely accept it immediately.

+1
source

Source: https://habr.com/ru/post/1241395/


All Articles