This is entirely wrong. Sure this is true if you're writing a general purpose programming language, but if you're writing an app or a game or a tool, you know the usage patterns because you are building them. You don't need to free things at "arbitrary" times, you free chunks at times when it is appropriate for your problem. You know more about your memory allocation patterns than any general purpose GC could ever know, and so you can write code to fit those better.
In a GC language, often you don't care about where and when the memory comes from, but sometimes you do, and when you do, you're stuck.