Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GC generation after resurrection?

Suppose an object has a Finalize() method.

When it is first created, a pointer in the finalization queue was added.

The object has no references .

When a garbage collection occurs, it moves the reference from the finalization queue to the f-reachable queue and a thread is started to run the Finalize method (sequentially after other objects' Finalize methods).

So the object now (after resurrection) has only one root which is the pointer from the f-reachable queue.

At this point, does/did the object get promoted to the next generation ?

like image 549
Royi Namir Avatar asked Oct 27 '12 20:10

Royi Namir


People also ask

How does generational garbage collection work?

Since Java uses generational garbage collection, the more garbage collection events an object survives, the further it gets promoted in the heap. It starts in the young generation and eventually ends up in the tenured generation if it survives long enough.

What is resurrection in C?

The phenomenon is known as resurrection. As the name suggests, an object is marked for destruction and in the last possible moment it is resurrected from the dead and reactivated. using system; public class B.

What is garbage collection C?

Garbage collection (GC) is a memory recovery feature built into programming languages such as C# and Java. A GC-enabled programming language includes one or more garbage collectors (GC engines) that automatically free up memory space that has been allocated to objects no longer needed by the program.

How often does Python garbage collect?

Any time a reference count drops to zero, the object is immediately removed. 295 * deallocated immediately at that time. A full collection is triggered when the number of new objects is greater than 25% of the number of existing objects.


2 Answers

This is something you can just try. Run this code in the Release build without a debugger attached:

using System;

class Program {
    static void Main(string[] args) {
        var obj = new Foo();
        // There are 3 generations, could have used GC.MaxGeneration
        for (int ix = 0; ix < 3; ++ix) {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
        Console.ReadLine();
    }
}

class Foo {
    int attempt = 0;
    ~Foo() {
        // Don't try to do this over and over again, rough at program exit
        if (attempt++ < 3) {
            GC.ReRegisterForFinalize(this);
            Console.WriteLine(GC.GetGeneration(this));
        }
    }
}

Output:

1
2
2

So it stays in the generation it got moved to by the collection, moving to the next one on each collection until it hits the last one. Which makes sense in general.

like image 165
Hans Passant Avatar answered Oct 23 '22 08:10

Hans Passant


It seems like the answer is yes, this will happen. http://msdn.microsoft.com/en-us/magazine/bb985010.aspx says:

... Two GCs are required to reclaim memory used by objects that require finalization. In reality, more than two collections may be necessary since the objects could get promoted to an older generation.

like image 33
Kendall Frey Avatar answered Oct 23 '22 10:10

Kendall Frey