Whether reference counting is a GC algorithm depends on how you define what GC is.
I prefer to consider GC only the methods of memory management where reclaiming the no longer used memory is done either asynchronously with the main program or as late as possible, i.e. when new allocation requests cannot be satisfied.
In the normal implementation of reference counting, memory is freed as soon as possible, i.e. exactly like stack memory, when blocks are exited, so I do not consider reference counting as GC.
The problem with GC in the strict sense is that you cannot predict when it will happen. With both stack memory and reference counted heap memory you know that whenever you exit a block, some time will be spent with running destructors and for freeing memory, but such interruptions will not happen in other points of the program.
> The problem with GC in the strict sense is that you cannot predict when it will happen.
It’s the same with ARC. You also don’t know when the counter will reach zero.
I define the academic view of GC algorithms in Computer Science, not what random developers decide to call GC.
Which in an industry where some folks call themselves Software Engineers after a bootcamp, without any kind of accreditation, I rather stay with the definition from those that do language design and compiler algorithms research.
> Whether reference counting is a GC algorithm depends on how you define what GC is.
Pretty much all the high-performance GC/refcounting algorithms are hybrids in one form or the other; it's a spectrum of choices. https://dl.acm.org/doi/10.1145/1028976.1028982 explores this in some detail.