Garbage Collector
Image: German, Public domain, Wikimedia Commons
In short: An automatic mechanism in many programming languages that frees memory no longer needed.
In more detail: Detects objects that can no longer be accessed in the program and frees the memory they occupy, without the programmer having to do it manually (unlike languages such as C++, where memory has to be explicitly freed). Runs automatically in the background in, for example, Java or JavaScript, but can cause brief delays (“GC pauses”) when it becomes active.
In Depth
The most common detection strategy is “reachability”: the garbage collector starts from a set of known root references (e.g. local variables on the stack, static fields) and traces all objects reachable from them. Everything NOT reachable from there counts as “garbage” and is freed — even if two objects reference each other, but nothing from outside points to them any more, both are correctly recognised as unreachable (unlike simpler reference counting, which can fail with such circular references).
Modern garbage collectors (e.g. Java’s G1 or ZGC) work generationally: newly created objects land in a small, frequently cleaned memory area (the “young generation”), since most objects are very short-lived anyway (e.g. temporary variables inside a method). Objects that survive several cleanup passes move into an “old generation”, which is searched less often, but more thoroughly. This minimises noticeable pauses during normal operation.
The big advantage over manual memory management (C, C++) is avoiding entire classes of bugs: no memory leak from a forgotten free, no crash from double-freeing or accessing already-freed memory. The price for that is less control over the exact timing of freeing, and a certain runtime overhead.
”Stop-the-world” pauses
A well-known problem with classic garbage collectors is “stop-the-world” pauses: while the cleanup pass runs, all application threads have to be briefly paused, so the reference structure doesn’t change in the middle of the analysis — with large heaps (lots of occupied memory), these pauses can last several hundred milliseconds, noticeable for time-critical applications like games or real-time trading systems. Modern collectors like ZGC or Shenandoah reduce these pauses to a few milliseconds, by doing most of the work concurrently with the running application, instead of pausing everything.
Languages without a garbage collector
Not every modern language relies on a classic garbage collector: Rust, for example, manages memory via an ownership system that checks at compile time when a value is no longer needed, and deterministically frees memory with no runtime overhead — a third way between manual management (C++) and an automatic garbage collector (Java), promising safety without the typical GC pauses, though with its own, demanding learning curve.