Garbage collection.
A tidy-up crew that clears away any object nobody is pointing at anymore, so you don’t free memory by hand.
Imagine a desk where you keep pulling out objects to work with, each tied to you by a piece of string so you can find it again. Some objects you finish with and drop — the string goes slack. A cleaner walks by now and then, follows every string from you, and bins anything no string still leads to.
Garbage collection is that cleaner for a program’s memory. Instead of you carefully freeing each object when you are done, the runtime tracks what is still reachable and automatically reclaims whatever has become unreachable.
- 1
A program makes lots of objects. Some are still in use; some you’ve quietly stopped needing.
- Anything loose?2
A collector comes by — not to read your objects, just to ask “is anyone still holding this?”
- 3
It starts from the roots and follows every reference, marking all it can reach.
- Nobody’s holding these.4
Whatever no live reference points to is unreachable — and gets swept away.
- 5
That memory goes back on the free pile, ready to be used again.
- Hold still a sec…6
The catch: it runs on its own schedule, and may briefly pause everything to clean up.
Reachable, not “unused”
A collector does not guess what you “need.” It keeps anything still reachable by following references from a set of roots — things like local variables and globals. If a chain of references leads to an object, it stays; if nothing points to it anymore, it is garbage, even if you meant to use it. That is why an accidental leftover reference can keep memory alive — a “leak” in a garbage-collected language.
The cost: it is not free
Collecting takes work, and many collectors must briefly pause the program to do it safely (a “stop-the-world” pause). Modern collectors hide most of this with clever, incremental work, but in latency-sensitive systems those pauses are something engineers actively tune around.