[sgen] Adjust free-ing of empty blocks
authorVlad Brezae <brezaevlad@gmail.com>
Fri, 2 Sep 2016 16:52:20 +0000 (16:52 +0000)
committerVlad Brezae <brezaevlad@gmail.com>
Mon, 12 Sep 2016 14:28:52 +0000 (17:28 +0300)
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.

mono/sgen/sgen-gc.h
mono/sgen/sgen-marksweep.c
mono/sgen/sgen-memory-governor.c

index dd5aef0392704810a21de0e4fe2de949104e2268..aefb07f23c5b6a99b9f3510a43d90c353f7a829d 100644 (file)
@@ -653,7 +653,7 @@ struct _SgenMajorCollector {
        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);
index d72913b001755054bf92df5e035fe13fd9d8be95..6798c240e7c2f0a3628d9607bf088cd9a873db51 100644 (file)
@@ -1957,11 +1957,8 @@ compare_pointers (const void *va, const void *vb) {
  * 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
index fea2c467e9ede17bf645a38e09b0c4ef63e9ec3f..dc69381547f60bfb192de3cbec934092f20022c3 100644 (file)
@@ -111,7 +111,7 @@ sgen_memgov_calculate_minor_collection_allowance (void)
 
        /* 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;