In what situation (s) would there be a link to an object that has been queued for garbage collection?

I read the C # topic in Dispose () and ~ finalize and when to use it. The author claims that you should not use links in your ~ finalize, because it is possible that the object you are referencing may already be assembled. In a specific example, for example, ".. you have two objects that have links to each other. If object # 1 is first assembled, then reference to object No. 2 points to an object that no longer exists."

In what scenarios should an instance of an object be in a state where it has a reference in memory to an object that is GC'd? I assume that there are at least two different scenarios, one of which points to an object reference and an object, where the object reference refers to another object reference (for example, when it was passed by the ref method in the method).

+7
source share
6 answers

You may have objects that reference each other, and the entire set may be eligible for GC.


Here is a simple code example:

class Test { public Test Other { get; set;} static void Main() { Test one = new Test(); Test two = new Test { Other = one; } one.Other = two; one = null; two = null // Both one and two still reference each other, but are now eligible for GC } } 
+12
source

Normally, the GC will only recover memory for objects that have no reference to them. However, objects with finalizers are handled differently.

Here's what MSDN says about it:

Recovering memory used by objects using Finalize methods requires at least two garbage collections. When the garbage collector runs collections, it restores memory for inaccessible objects without finalizers. At this time, he cannot collect inaccessible objects that have finalizers. Instead, it removes the entries for these objects from the finalization queue and places them in the list of objects marked as ready for completion. [...]
The garbage collector calls Finalize methods on the objects in this list, and then removes the entries from the list. Future garbage collection will determine that finalized objects are truly garbage, because they no longer point to entries in the list of objects marked as ready to be completed.

Thus, there is no guarantee that other objects referenced in the finalizer will continue to be used when the GC code is Finalize , as they may have already been finalized during earlier garbage collection, while the object was waiting for completion .

+4
source

In short, objects inaccessible from the GC root (static field, method parameter, local variable, registered variable), following a chain of links, have the right to garbage collection. Thus, it is possible that, say, an object A refers to B, which refers to C, which refers to D, but suddenly A cancels its reference to B, in which case all B, C and D can be assembled.

+2
source

"... then the reference to object # 2 points to an object that no longer exists."

It will never happen. Whenever your code has access to a link, the referenced object still exists. This is called memory security, and it persists when an object completes in the background. The link never points to the assembled instance.

But an already existing, not assembled object can already be completed (deleted). This probably refers to your warning.

 class Foo { private StreamWriter logFile = ... private StringBuilder sb = new StringBuilder("xx"); ~Foo() { if (sb.ToString() == "xx") // this will always be safe and just work { // the next line might work or // it might fail with "logFile already Disposed" logFile.Writeline("Goodbye"); } } } 
+1
source

Unfortunately, there is a lot of careless use of terminology related to garbage collection, which causes a lot of confusion. The “elimination” or “finalizer” does not actually destroy the object, but rather serves to delay the destruction of the object, which might otherwise have the right to destruction, while after it had the opportunity to put its affairs in order (that is, generally speaking, letting other things know that their services are no longer required).

It’s easiest to think of a “stop the world” garbage collector by following these steps to:

  • Check all items that are new enough to be considered garbage.
  • Visit every root of the garbage collector (that is, a thing that is essentially “living”), and if it has not yet been copied, copy it to a new heap, update the link to point to the new object, and all the elements to which it contains links (which will copy them if they were not copied). If someone visits an item in an old heap that has been copied, just update the link used to visit it.
  • Inspect each item registered for finalization. If it has not already been copied, cancel it for final revision, but add a link to it in the list of objects that should be completed as quickly as possible.
  • Elements of the immediate update list are considered "live", but since they have not yet been copied, visit each element in this list and, if it has not yet been copied, copy it to a new heap and view all the elements to which it has links.
  • Drop the old heap, as no one else will refer to anything on it.

It is interesting to note that although some other garbage collection systems operate using pointers with double indirect access for links, the .net garbage collector (at least the usual “stop the world”) uses direct pointers. This slightly increases the workload of the collector, but it improves the efficiency of the code that controls the objects. Since most programs spend more time manipulating objects than collecting garbage, this is a clear victory.

+1
source

In .NET, there is a term called resurrection.

In short, resurrection can occur when your object is in the finalization queue, but when the finalizer ( ~ClassName() ) method is called, it moves the object back into the game. For example:

 public class SomeClass { public static SomeClass m_instance; ... ~SomeClass() { m_instance = this; } } 

Read more about this here: Resurrecting an object using GC.ReRegisterForFinalize . But I would really recommend the CLR book through C # by Jeffrey Richter, as she explained this in detail in one of the chapters.

0
source

All Articles