Equalize promoted (#64206)
I have observed that in server GC scenarios, the amount of promoted memory is often very uneven between heaps, which leads to suboptimal work distribution between server GC threads.
The PR introduces a new method equalize_promoted_bytes that attemps to even out the promoted memory between heaps by moving regions from heaps with lots of promotion of heaps with less promotion.
The algorithm used removes regions from heaps that have more than average promotion. These surplus regions are arranged into size classes by the amount of promoted memory in them. The heaps are also arranged into size classes by how much their promoted memory is short of the average promoted memory per heap.
Then we repeatedly move the surplus region with the most promoted memory to the heap with the biggest deficit. If the heap still has a deficit, it is reconsidered under its new deficit size class. Otherwise, it now has average or more promoted memory and is removed from further consideration.
Because regions may now move between heaps, it is no longer true that the finalization queue entry for an object is always on the same heap as the object itself. This necessitated moving the call to finalize_queue->UpdatePromotedGenerations to a later point in time when all threads have finished updating the final generation for a region.