0

so I'm just practicing my coding in C#, and I'm trying to figure out why my logic isn't granting me the result of decreasing a static integer when I set an object to null, and proceed to collect garbage.

I haven't really tried anything yet, this is a question more so in regards to why this outcome is happening, I call WriteLine() after setting the object pointer to null to see how many spaceships have been made, and it says 1 still, even after garbage collecting. (which I think isn't even necessary to do.)

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{

    static class Information
    {
        public static int Spaceships_Made = 0;
    }


    class Spaceship
    {
        public Spaceship()
        {
            Information.Spaceships_Made++;
            Console.WriteLine("Spaceships : {0}",    Information.Spaceships_Made);
        }
        ~Spaceship()
        {
            Information.Spaceships_Made--;
            Console.WriteLine("Spaceships : {0}", Information.Spaceships_Made);
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Spaceship Apollo = new Spaceship();
            Apollo = null;
            GC.Collect();
            Console.WriteLine(Information.Spaceships_Made);
            Console.ReadKey();
        }
    }
}

I expect the result from calling WriteLine to be 0, as I attempt to completely wipe out the Apollo pointer I just made, but it appears to still have a value of 1.

  • 1
    Could you edit the question to include the exact console output you see? – Joe Sewell Jul 01 '19 at 18:42
  • Possible duplicate of https://stackoverflow.com/questions/44573392/c-sharp-my-destructor-isnt-being-called –  Jul 01 '19 at 18:44
  • 5
    Finalizers in C# aren't called the way destructors are called in C++. I've only been writing C# professionally for 11 years, and I've never yet had occasion to write a finalizer, which should give you a sense of where this ought to rank among your priorities while learning the language (some better options: Minecraft, taking a nap). But here you are. I'd change the format string in the finalizer so you can tell when/if the finalizer, as opposed to the constructor, is being called. See when or if you ever even hit that code. – 15ee8f99-57ff-4f92-890c-b56153 Jul 01 '19 at 18:44
  • 1
    Using the debugger might prevent the finalizer from being called at all. See Eric Lippert's answer in my link. –  Jul 01 '19 at 18:45

1 Answers1

3

Try adding a sleep before your GC to solve your immediate problem... Also you might GC twice. The GC is unpredictable and can be updated with new unpredictable behavior at any time.

In general though, don't rely on the behavior of a specific garbage collector manage your own instance counts. For instance, instead of saying Apollo = null, call Apollo.selfDestruct() and have THAT decrement the instance count.

This has the added benefit of not breaking if some other class happens to have an instance of your spaceship and you aren't aware (in which case setting the instance to null will never destroy it)

Bill K
  • 62,186
  • 18
  • 105
  • 157