There are some performance advantages a garbage collector can have over manual memory management. If you're just calling malloc/free or, in C++, calling new/delete in constructors/destructors (or using a class that does so, like std::vector), and nothing special, the garbage collector is probably allocating memory faster.
> controlling memory layout
Garbage collectors can compact active memory into one contiguous location and adjust the active pointers to point there instead. You can't do this in a language like C, because you can have arbitrary pointers to anything, and there's no runtime indication of what's a pointer or just an integer. You simply have to prevent memory fragmentation in the first place, which also complicates the logic of the program.
For faster allocation in C, arena allocation based on object lifetimes can be used [1]; in generational garbage collectors, you get similar benefits, but it's just done automatically. In fact, in that linked paper, they found that lifetime-based arena allocation improved the speed of their program (a C compiler) at the cost of increased memory allocation compared to naïve malloc() and free(), which is exactly what garbage collection does.
As a result of compaction, memory allocation with garbage collection is just a pointer bump in the best case, whereas allocation with just malloc usually requires searching a free list or a tree.
[1]: https://www.cs.princeton.edu/techreports/1988/191.pdf