After sweep, depending on the computed allowance, we are freeing empty blocks so that we still keep around enough blocks to fill that allowance (to avoid repeated vmaps).
On both collectors this had the problem that the allowance also accounts for LOS space, which we shouldn't account for in major section heuristics (which means that in LOS intensive benchmarks we only free major sections after the LOS shrinks).
On the concurrent collector, where we have a negative allowance adjustment depending on the duration of the concurrent mark (in order to mimic serial memory usage), we can have very small allowances at the end of a major collection, even 0. This means that we would reserve no empty blocks for later use.
We solve these issues by reserving empty blocks relative to the amount of current alive blocks, which is also the basis of how we compute the allowance in the first place.
void (*sweep) (void);
gboolean (*have_swept) (void);
void (*finish_sweeping) (void);
- void (*free_swept_blocks) (size_t allowance);
+ void (*free_swept_blocks) (size_t section_reserve);
void (*check_scan_starts) (void);
void (*dump_heap) (FILE *heap_dump_file);
gint64 (*get_used_size) (void);
* This is called with sweep completed and the world stopped.
*/
static void
-major_free_swept_blocks (size_t allowance)
+major_free_swept_blocks (size_t section_reserve)
{
- /* FIXME: This is probably too much. It's assuming all objects are small. */
- size_t section_reserve = allowance / MS_BLOCK_SIZE;
-
SGEN_ASSERT (0, sweep_state == SWEEP_STATE_SWEPT, "Sweeping must have finished before freeing blocks");
#ifdef TARGET_WIN32
/* FIXME: Why is this here? */
if (major_collector.free_swept_blocks)
- major_collector.free_swept_blocks (allowance);
+ major_collector.free_swept_blocks (major_collector.get_num_major_sections () * SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO);
major_collection_trigger_size = new_heap_size + allowance;