The problem I see with the GC and with immutable data structures is somewhat unbounded memory consumption.
In former, and general, case because it takes uncertain amount of time for objects to be released and memory to be reclaimed.
In latter case because of essentially creating and then keeping the snapshots of the same but slightly different data that is also going to be released at some uncertain moment.
In high concurrency scenarios, for both of these cases, peak memory consumption is going to present a problem. Imagine a database kernel servicing hundreds, if not thousands, if requests at the same time. Machine will eventually run out of the memory under see high pressure and at that moment you will either swap or die. Choose your poison.
But to be honest you don't need neither of those to run into such unbounded memory consumption problems. It's enough to litter your codebase with unwieldy use of std::shared_ptr and it will have the same effect.
Probably, I don't know if GC can be that precise and timely. But nonetheless my point actually was that this is more inevitable to happen in case of immutable datastructures than with lock-free or mutex-ey sharded design.
In former, and general, case because it takes uncertain amount of time for objects to be released and memory to be reclaimed.
In latter case because of essentially creating and then keeping the snapshots of the same but slightly different data that is also going to be released at some uncertain moment.
In high concurrency scenarios, for both of these cases, peak memory consumption is going to present a problem. Imagine a database kernel servicing hundreds, if not thousands, if requests at the same time. Machine will eventually run out of the memory under see high pressure and at that moment you will either swap or die. Choose your poison.
But to be honest you don't need neither of those to run into such unbounded memory consumption problems. It's enough to litter your codebase with unwieldy use of std::shared_ptr and it will have the same effect.