0

Guess the title must have provided you with the sufficient idea of what I want to know, but I must elaborate it a little here, so that you can get the exact idea.

I know the following about the Finalize method:

  1. We need to create a destructor in C# using ~Classname inside the class. According to C#, Finalize & destructors are synonyms (I read it on MSDN, I don't know if the last part of the statement is even correct or not).

  2. It is used to "gracefully release the unmanaged resources".

  3. It can be called by the user (developer) accordingly, or when the application is running short on memory (managed heap), or at the end of the application.

  4. Any object having the Finalize method will be added to the finalization queue during runtime.

The following image is taken from MSDN Magazine Article. It shows the Roots, Managed Heap (MH), Finalization Queue (FQ) & Freachable Queue (F-RQ). All this process occurs during runtime.

IMAGE 1


My questions are as follows:

  1. How does the references to, objects present in MH are added to FQ? (Means, are they automatically added to FQ because they have Finalize or GC adds them by keeping their track.)

  2. Does GC runs through FQ as well to clear the references? (For the object references that uses GC.SuppressFinalization.)

  3. If MH has enough memory for the incoming objects for sometime, but at the same time the special thread in F-RQ is done with the Finalize method of the reference(s) present in the F-RQ than, at that instant will GC run specially for F-RQ to reclaim the memory or will it run for both MH & F-RQ or will it wait until MH falls short on memory?

EDIT:

For question 3: Consider the following image with all the references in F-RQ not reachable.

IMAGE2

If there are any mistake(s) in the above stated questions or knowledge, feel free to point it out & an explanation to it will be really appreciated.

IS4
  • 11,945
  • 2
  • 47
  • 86
phougatv
  • 881
  • 2
  • 12
  • 29

1 Answers1

2
  1. The GC adds objects to the finalizer queue when they have a finalizer. I don't understand your distinction between "automatically added because they have Finalize" and "GC adds them". The GC adds them because they have a finalizer. From the programmer's point of view, it's automatic.

  2. When an object calls GC.SuppressFinalize(), it's flagged as not needing finalization. There's no need for the GC to later "run through" the queue to remove that object's reference. It's simply ignored when the queue is processed.

  3. Yes. I.e. first, there is no one "GC"…several different implementations for .NET exist. Second, the GC is complex enough that its behavior can't really be summarized like that.

Note that all of this is implementation detail. Here's what we as users of C# need to know:

  • If we use unmanaged resources that cannot be managed via the SafeHandle class, we need to add a finalizer to our class, and in the finalizer release those resources.
  • We also need to implement IDisposable in that case (among others), and in our implementation call GC.SuppressFinalize() so that the GC knows to not waste time running our finalizer.

The rest can change at any time. It might be interesting academically, or if you're looking to write your own GC. But otherwise, it's not generally actionable information.

In addition to the article you've already referenced, you might also be interested in:

MSDN Blogs > cbrumme's WebLog > Finalization

Object.Finalize Method – How finalization works

SO: Generational Garbage collection Vs Garbage collection in .NET

Community
  • 1
  • 1
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • @Peter By **`automatically added because they have Finalize`** I mean if an object has **`Finalize`** method, does it automatically gets to **`FQ`** of its own on runtime. And by **`GC adds them`** I mean, when an object has a **`Finalize`** method than at runtime it is tracked an added by **`GC`** in **`FQ`**. – phougatv Nov 12 '14 at 09:10
  • @LasseV.Karlsen No offence, but as far as I've know, **`Finalize Queue`** & **`F-Reachable Queue`** or **`Freachable Queue`** are 2 different data structures, both controlled by **`GC`** – phougatv Nov 12 '14 at 09:15
  • @PeterDuniho During the runtime, when `GC` finds any objects with `Finalize` it adds it to **`MH`** and their references to **`FQ`** and to execute their **`Fianlize`** method **`GC`** adds the object to **`F-RQ`**. – phougatv Nov 12 '14 at 09:21
  • @beginner: according to the sources I've read (including the first link in my answer), the object with a finalizer is added to the finalization queue when it is first created. – Peter Duniho Nov 12 '14 at 09:23
  • @LasseV.Karlsen Sure! go ahead. – phougatv Nov 12 '14 at 09:23
  • 1
    @beginner: at runtime, when an object is created it's already part of the managed heap. If it has a finalizer, it's also added to the finalization queue. When the object in the finalizer queue is eligible for collection, it's put in the freachable queue. I believe the referenced links include this information. – Peter Duniho Nov 12 '14 at 09:27
  • According to your explanation for **`Question : 3`**, **`GC`** can make a special run to clear the **`F-RQ`** only. If that's what you meant by **the GC is complex enough that its behavior can't really be summarized like that.** – phougatv Nov 12 '14 at 09:28
  • 1
    @beginner: I'm saying that the GC runs its threads at times controlled by the GC's own algorithms. I don't actually know the exact specifics of the current implementation, but it would not surprise me to find that the finalizer thread (assuming there's still only one) sometimes can run immediately, and sometimes cannot. – Peter Duniho Nov 12 '14 at 09:31
  • Well your links seems pretty helpful, thanks. I will raise another query(if I come across one) once I'm done with them. ;) – phougatv Nov 12 '14 at 09:47