Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Garbage collection - One works but not the other, how come? [duplicate]

So I have this simply Bell class that I'm testing garbage collection on:

public class Bell
{
    public void Ring()
    {
        Console.WriteLine("Ding ding");
    }
}

If I run this code segment below, it doesn't get garbage collected

class Program
{
    private static WeakReference reference;

    private static void Main()
    {
        Console.WriteLine("Starting");

        var bell = new Bell();
        reference = new WeakReference(bell);
        bell = null;

        GC.Collect();

        Console.WriteLine("Object still alive: {0}", reference.IsAlive);

        if (reference.Target == null)
        {
            Console.WriteLine("Bell is no more!");
        }
        else
        {
            {
                var theBell = (Bell)reference.Target;
                theBell.Ring();
            }
        }

        Console.ReadLine();
    }
}

If I however only check reference.IsAlive like below, it's garbage collected

class Program
{
    private static WeakReference reference;

    private static void Main()
    {
        Console.WriteLine("Starting");

        var bell = new Bell();
        reference = new WeakReference(bell);
        bell = null;

        GC.Collect();

        Console.WriteLine("Object still alive: {0}", reference.IsAlive);

        Console.ReadLine();
    }
}

Can you guys explain to me how this works?

like image 282
Christian M.P. Avatar asked Feb 12 '15 09:02

Christian M.P.


2 Answers

You're trying to test it with debug mode. GC isn't aggressive in debug mode as it behaves in release mode(with optimize switch turned on). This makes debugging easy, otherwise you'll find strange things while debugging. For example: You may try to inspect the value of already garbage collected variable.

Run the code in release mode and you can see Bell will be GC'd.

like image 169
Sriram Sakthivel Avatar answered Oct 18 '22 19:10

Sriram Sakthivel


That's because of your object type of reference (source)

Represents a weak reference, which references an object while still allowing that object to be reclaimed by garbage collection.

And following could probably explain why two scenarios behave differently (Source)

A weak reference permits the garbage collector to collect the object while still allowing the application to access the object. A weak reference is valid only during the indeterminate amount of time until the object is collected when no strong references exist. When you use a weak reference, the application can still obtain a strong reference to the object, which prevents it from being collected. However, there is always the risk that the garbage collector will get to the object first before a strong reference is reestablished.

After several runs [With some test cases] : my opinion

The if-else is the key I think. After Writeline, Object is re-refer allowing to get a strong reference before GC clean the object.

Again this phrase is the key

However, there is always the risk that the garbage collector will get to the object first before a strong reference is reestablished.

like image 37
Kavindu Dodanduwa Avatar answered Oct 18 '22 17:10

Kavindu Dodanduwa