From: Vlad Brezae Date: Wed, 28 Oct 2015 20:29:11 +0000 (+0200) Subject: [sgen] Finish concurrent collection if the heap grows too much X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=7b05a82b56a69a288baa4e7b98f05b98097ca9d7;p=mono.git [sgen] Finish concurrent collection if the heap grows too much In order to achieve this, when asked to do a major collection, we finish the concurrent collection immediately, regardless if we are explicitely requested or not to wait_to_finish. --- diff --git a/mono/sgen/sgen-conf.h b/mono/sgen/sgen-conf.h index 11a8998478e..5a0e871e22f 100644 --- a/mono/sgen/sgen-conf.h +++ b/mono/sgen/sgen-conf.h @@ -190,6 +190,12 @@ typedef mword SgenDescriptor; */ #define SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO 0.33 +/* + * How much more we allow the heap to grow, relative to the allowance, while doing + * a concurrent collection, before forcing its finish. + */ +#define SGEN_DEFAULT_CONCURRENT_HEAP_ALLOWANCE_RATIO 0.25 + /* * Default ratio of memory we want to release in a major collection in relation to the the current heap size. * diff --git a/mono/sgen/sgen-gc.c b/mono/sgen/sgen-gc.c index 9a8d10806da..6dd730dcbe9 100644 --- a/mono/sgen/sgen-gc.c +++ b/mono/sgen/sgen-gc.c @@ -2182,7 +2182,7 @@ sgen_ensure_free_space (size_t size) generation_to_collect = GENERATION_OLD; } } else if (sgen_need_major_collection (size)) { - reason = "Minor allowance"; + reason = concurrent_collection_in_progress ? "Forced finish concurrent collection" : "Minor allowance"; generation_to_collect = GENERATION_OLD; } else { generation_to_collect = GENERATION_NURSERY; @@ -2229,18 +2229,18 @@ sgen_perform_collection (size_t requested_size, int generation_to_collect, const if (concurrent_collection_in_progress) { /* - * We update the concurrent collection. If it finished, we're done. If - * not, and we've been asked to do a nursery collection, we do that. + * If the concurrent worker is finished or we are asked to do a major collection + * then we finish the concurrent collection. */ - gboolean finish = major_should_finish_concurrent_collection () || (wait_to_finish && generation_to_collect == GENERATION_OLD); + gboolean finish = major_should_finish_concurrent_collection () || generation_to_collect == GENERATION_OLD; if (finish) { major_finish_concurrent_collection (wait_to_finish); oldest_generation_collected = GENERATION_OLD; } else { + SGEN_ASSERT (0, generation_to_collect == GENERATION_NURSERY, "Why aren't we finishing the concurrent collection?"); major_update_concurrent_collection (); - if (generation_to_collect == GENERATION_NURSERY) - collect_nursery (NULL, FALSE); + collect_nursery (NULL, FALSE); } goto done; diff --git a/mono/sgen/sgen-memory-governor.c b/mono/sgen/sgen-memory-governor.c index 824d2f7183c..ce34f7f4a67 100644 --- a/mono/sgen/sgen-memory-governor.c +++ b/mono/sgen/sgen-memory-governor.c @@ -112,13 +112,32 @@ sgen_memgov_calculate_minor_collection_allowance (void) } } +static inline size_t +get_heap_size (void) +{ + return major_collector.get_num_major_sections () * major_collector.section_size + los_memory_usage; +} + gboolean sgen_need_major_collection (mword space_needed) { size_t heap_size; - if (sgen_concurrent_collection_in_progress ()) + if (sgen_concurrent_collection_in_progress ()) { + heap_size = get_heap_size (); + + if (heap_size <= major_collection_trigger_size) + return FALSE; + + /* We allow the heap to grow an additional third of the allowance during a concurrent collection */ + if ((heap_size - major_collection_trigger_size) > + (major_collection_trigger_size + * (SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO / (SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO + 1)) + * SGEN_DEFAULT_CONCURRENT_HEAP_ALLOWANCE_RATIO)) { + return TRUE; + } return FALSE; + } /* FIXME: This is a cop-out. We should have some way of figuring this out. */ if (!major_collector.have_swept ()) @@ -129,7 +148,7 @@ sgen_need_major_collection (mword space_needed) sgen_memgov_calculate_minor_collection_allowance (); - heap_size = major_collector.get_num_major_sections () * major_collector.section_size + los_memory_usage; + heap_size = get_heap_size (); return heap_size > major_collection_trigger_size; } @@ -150,7 +169,7 @@ sgen_memgov_major_collection_start (void) need_calculate_minor_collection_allowance = TRUE; if (debug_print_allowance) { - SGEN_LOG (0, "Starting collection with heap size %ld bytes", (long)(major_collector.get_num_major_sections () * major_collector.section_size + los_memory_usage)); + SGEN_LOG (0, "Starting collection with heap size %ld bytes", (long)get_heap_size ()); } }