A garbage collector deallocates unused allocated memory from time to time. This way, in Haskell memory deallocation can be hidden, making the language (more) declarative.
A simple idea of implementing a garbage collector would be to count the references to an object and delete the object when the last reference disappears.
However, in cyclic data structures like
let x = 'a':x in x, the
x is referenced by itself, so it would never be deallocated. Thus garbage collection is a bit more complicated and thus needs more effort and phases, where it is applied.
Garbage collection is also a bit difficult to handle with respect to real-time processing. You cannot precisely control when something gets deallocated and in real-time processing the garbage collector might just choose the wrong time point. However, in long running (server) applications you might encounter memory leaks that are not easily observed in programs that run only a short time. A memory leak does not only mean that more and more memory is allocated but it also means that the garbage collector has to verify the reachability of an increasing number of pieces of data.