Like other languages that assume the existence of a garbage collector, C# is designed so that the garbage collector may implement a wide range of memory management policies. For instance, C# does not require that destructors be run or that objects be collected as soon as they are eligible, or that destructors be run in any particular order, or on any particular thread.
The behavior of the garbage collector can be controlled, to some degree, via static methods on the class System.GC. This class can be used to request a collection to occur, destructors to be run (or not run), and so forth.
Since the garbage collector is allowed wide latitude in deciding when to collect objects and run destructors, a conforming implementation may produce output that differs from that shown by the following code.
- using System;
- using System.Text;
-
- namespace forgetCode
- {
-
- class A
- {
- ~A()
- {
- Console.WriteLine("Destruct instance of A");
- }
- }
- class B
- {
- object Ref;
- public B(object o)
- {
- Ref = o;
- }
- ~B()
- {
- Console.WriteLine("Destruct instance of B");
- }
- }
-
-
- class program
- {
- public static void Main()
- {
-
- B b = new B(new A());
- b = null;
- GC.Collect();
- GC.WaitForPendingFinalizers();
- }
- }
- }
Output:
Destruct instance of B
Destruct instance of A
or
Destruct instance of A
Destruct instance of B
The output could be either because the language imposes no constraints on the order in which objects are garbage collected.