In summary,
Advantages:
A. Objects are collected immediately when they become garbage.
B. Programming language runtime support is simpler.
C. Memory can be reclaimed easily in programs with distributed heaps.
Disadvantages:
A. Natural race conditions exist in multi-threaded programs when reference counting is used. Atomic read/writes are necessary when incrementing/decrementing the reference count for an object.
B. Cyclic data structures cannot be reclaimed. (This is why you have to jump through hoops to avoid this in Objective-C and Swift.)
C. Every object in your language which is reference counted needs a field to hold the reference count. Or you need a special object in its stead which "points" to your object, like a shared pointer.
D. Pauses with reference counting are still possible. As stated in the book, "When the last reference to the head of a large pointer structure is deleted, reference counting must recursively delete the descendant of the root."