There is such a thing as reference counting :)
Non-trivial reference counting starts to look like mark-and-sweep GC.
And even then, when a ref count drops to zero, the runtime cost of destruction and deallocation of particular objects can be expensive. Stop-the-world GC is bad, but “make a blocking call because you can’t use async APIs in destructors” is worse - especially when the destructor runs in a program thread instead of a GC thread.
I feel that languages which provide support for defined object ownership and lifetime (Rust, any others?) will become the future because in many scenarios object-lifetime can be nailed-down by the compiler and thus eliminate the need for GC or ARC.
But yes, it's malloc and free.
[1]: https://www.cs.virginia.edu/~cs415/reading/bacon-garbage.pdf
Go and C# running circles around Swift.
"35C3 - Safe and Secure Drivers in High-Level Languages"
https://www.youtube.com/watch?v=aSuRyLBrXgI
Possible stack overflows and unexpected pauses due to heavily nested data structures.
"CppCon 2016: Herb Sutter “Leak-Freedom in C++... By Default."