There is nothing that prevents a GCed language to allocate things on the stack. Also I'm afraid using std::string in C++ causes more allocs/frees than typical use of Strings in Java/C#, because the former can't be safely shared and must be copied - on the heap.
A GCed language requires good stack escape analysis. Unless you expose it to the programmer for at least semi-manual MM, it is bound to have false negatives, where you pay for the allocation on the heap unnecessarily.
I totally agree about std::string.
I think C++ with the conventional libraries is actually an example of how to do manual MM badly.