The GC is nondeterministic as to when it will get called, exactly. It is not an immediate matter that memory is freed the instance that it's no longer used, it happens when the computer is open enough to do it. In many cases, this can be sooner rather than later, but there's still no guarantee that it will happen immediately.
That's why methods like GC.Collect()
exist. In most cases we don't have to worry, because we're dealing with small enough variables and enough RAM that "eventually" is more than sufficient for our uses. The garbage collector is offered as a utility, not a deity. It's useful, because it works in almost every case (particularly in applications cases). And in most cases, we don't have to worry about storing all that much data (if we do in applications, we might want to review our design to implement some paging to not display as much at once in the first place). But just because we're using managed memory is no promise that it will be managed in a solid, 100% way and that we can throw anything at them.
That's one of the reasons languages like C++ still exist. As you said, the GC is very smart, and very good at its job. So it's nice not to have to think about malloc
and free
and just to rest some trust on that, but that doesn't mean it can read our minds.
It's kind of like cruise control. You can drive down the road and set cruise control to maintain a constant speed, but when you start to climb a hill, it will take a moment to catch up and start increasing your throttle to maintain the speed. Similarly, it will let you fall down the hill more quickly than you might have otherwise. The GC is aware of what objects are free-able in memory, but it is not necessarily aware of the details of the context, and the idea is that it acts passively behind our code. Otherwise, it would cause some severe performance issues.
As many other people have also noted, and I think is important in a more practical sense, the GC will, of course, only collect resources that are no longer in use or scope. Thus, if the elements in your Dictionary
are used elsewhere (and are passed by references, i.e. are class
s), they will not be collected. Furthermore, if you keep your Dictionary
as a static
member, it will never be collected.