"doesn't spot cyclical structures"
Let's say I've got an object A
. A
needs another object called B
to do its work. But B
needs another object called C
to do its work. But C
needs a pointer to A
for some reason or other. So the dependency graph looks like:
A -> B -> C -> A
The reference count for an object should be the number of arrows pointing at it. In this example, every object has a reference count of one.
Let's say our main program created a structure like this during its execution, and the main program had a pointer to A
, making A
's count equal to two. What happens when this structure falls out of scope? A
's reference count is decremented to one.
But notice! Now A
, B
, and C
all have reference counts of one even though they're not reachable from the main program. So this is a memory leak. Wikipedia has details on how to solve this problem.
"it can reclaim space incrementally"
Most garbage collectors have a collection period during which they pause execution and free up objects no longer in use. In a mark-and-sweep system, this is the sweep step. The downside is that during the periods between sweeps, memory keeps growing and growing. An object may stop being used almost immediately after its creation, but it will never be reclaimed until the next sweep.
In a reference-counting system, objects are freed as soon as their reference count hits zero. There is no big pause or any big sweep step, and objects no longer in use do not just sit around waiting for collection, they are freed immediately. Hence the collection is incremental in that it incrementally collects any object no longer in use rather than bulk collecting all the objects that have fallen out of use since the last collection.
Of course, this incrementalism may come with its own pitfalls, namely that it might be less expensive to do a bulk GC rather than a lot of little ones, but that is determined by the exact implementation.