Even if you don't think about memory management, and do the naive thing in rust or rc in some other systems language, gc only comes out ahead in that many tiny objects case. Which is very domain specific. I don't ever run into that situation, or if I do, they are homogeneous in type so I handle them in bulk, not individually.
That depends on what you mean by GC. There are refcounting GCs, there are mark-and-sweep tracing GCs (like the one Go uses), and there are moving GCs (the last ones are the ones used in Java, V8, and .NET). Moving GCs win in many situations because they're just a really efficient algorithm both in theory and in practice (they win on speed, and the tradeoff is footprint). The downside is that they require 1. a lot of expertise and effort to implement (in fact, the first open-source, high-throughput, low-latency pauseless moving GC only appeared 3 years ago), which is why only specialised expert teams have implemented them, and 2. that virtually all pointers can move, which means that interop with low-level code requires some specialised API. That last restriction means that low-level languages generally cannot enjoy the optimisations that moving collectors bring.