When I started writing Giggle, I didn't understand the issues involved in garbage collection. I didn't know I didn't understand those issues because I hadn't implemented a garbage collector & because no one who understood them had explained them to me.
I learned a lot about garbage collection through implementing Giggle.
Among other things, I learned that no garbage collector at all, regardless of the algorithm it uses, ever will be able to find & recycle all unused memory in the order you want in the general case. If your data has no referential cycles, the garbage collector probably can recycle memory in the order you want. If your data does have referential cycles, the garbage collector can either fail to recycle the memory involved, or it can guarantee to recycle everything, but it might do so in an order that's inconvenient for you. This is an unavoidable fact of garbage collection, though I'm not going to explain it here. I've written a little about it in ``The Proper Use of Garbage Collection in C++'' (http://gms.freeshell.org/essays/garbage-collection-cpp/.
(There should be articles somewhere describing garbage collection's limitation without requiring the reader to understand garbage collection theory, but I haven't found any yet. In the mean time, if you can't take my word for it, implement a garbage collector system for yourself. Either you'll prove me wrong or you'll end up agreeing.)
If a language doesn't have destructors, this doesn't matter, but C++ has destructors, so this matters. The solution is to recognize that destructors are part of object management while garbage collection is part of memory management, & the two are separate. The reason C++ programmers see this limitation of garbage collection as a flaw is that we've long used destructors to implement ad hoc memory management.