Of the general-purpose methods it does; that's is exactly what these collectors were invented for - not to carry all that overhead of malloc/free. I guess you could argue over the frequency of situations where it yields a significant boost. It's also true that malloc/free have also improved, especially in the very large runtimes (like TCMalloc and jemalloc), but they can't do all the optimisations moving collectors can.
It’s great that they were created for this purpose, but I have a faster allocator in non-moving GC engine in C++. And I don't have to moving gigabytes of data.
Generational moving allocators don't move objects much, and so the total amount of work they need to do is substantially less than malloc/free allocators -- that's the whole idea of these algorithms and the reason why they're used (that's not under dispute; it's just the mathematics of the algorithms [1]). Still, there might be some situations where allocators in C++ could be faster, but if that were the case for my purposes, I would have stuck with C++. We needed very good performance for highly concurrent workloads, and C++ just doesn't come close in many of those (maybe at 10x the budget).
[1]: More precisely, the work they need to do doesn't scale linearly with the allocation rate as is the case with non-moving approaches. Of course, arenas are sort of degenerate moving collectors, so they also display the same effect, but they can't always be used.
The way this works is that you allocate in the young generation with a pointer bump, and to free memory you compact (move) the surviving objects, which make up a small minority, a few times and then promote (move) them to the old generation (where you either manage memory with the same technique or a different one). And so the total amount of moving is not high (objects either never move or rarely move), and what you end up with is essentially two heaps, one where the allocation rate may be high but you can completely negate all the extra work by increasing the size of that heap, and one where the allocation rate is low. This ability to, optionally, not double the amount of work when the allocation rate doubles is what gives moving collectors their efficiency (and that you can bump-allocate in virtually all cases).
Of course, it's possible to come up with programs where objects do move a lot (or there's some other common work), e.g. programs that don't exhibit the behaviour of the generational hypothesis, but the point is that in a very large class of programs, this technique is hard to compete with.
[–] pron 1 day ago
[–] pebal 1 day ago
[–] pron 1 day ago
[1]: More precisely, the work they need to do doesn't scale linearly with the allocation rate as is the case with non-moving approaches. Of course, arenas are sort of degenerate moving collectors, so they also display the same effect, but they can't always be used.
The way this works is that you allocate in the young generation with a pointer bump, and to free memory you compact (move) the surviving objects, which make up a small minority, a few times and then promote (move) them to the old generation (where you either manage memory with the same technique or a different one). And so the total amount of moving is not high (objects either never move or rarely move), and what you end up with is essentially two heaps, one where the allocation rate may be high but you can completely negate all the extra work by increasing the size of that heap, and one where the allocation rate is low. This ability to, optionally, not double the amount of work when the allocation rate doubles is what gives moving collectors their efficiency (and that you can bump-allocate in virtually all cases).
Of course, it's possible to come up with programs where objects do move a lot (or there's some other common work), e.g. programs that don't exhibit the behaviour of the generational hypothesis, but the point is that in a very large class of programs, this technique is hard to compete with.