I have a class:
public class SomeClass { public int I; public SomeClass(int input) { I = input; Console.WriteLine("I = {0}", I); } ~SomeClass() { Console.WriteLine("deleted"); } public void Foo() { Thread.Sleep(1000); Console.WriteLine("Foo"); } }
and this program:
class Program { static void Main(string[] args) { new Thread(() => { Thread.Sleep(100); GC.Collect(); }) { IsBackground = true }.Start(); new SomeClass(10).Foo();
When I run this code in debug mode , I have the following result:
I = 10 Foo deleted
but when I change the mode to Release , the result will change to:
I = 10 deleted Foo
As I understand it, the difference is with call and callvirt : when optimization starts in Release mode, the compiler looks at the Foo method and cannot find a link to SomeClass in this method and why this method is called as a static method at the address, and the garbage collector can collect this object.
Otherwise, if I change the Foo method (for example, add Console.WriteLine(I) to this method), the compiler will not decide to call this method as call , and it must be called by the pointer to the instance using callvirt and the garbage collector will not collect this object.
Can you explain more clearly what is happening here (why the GC can assemble the object, and if so, how the method works).
source share