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.
*/
#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.
*
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;
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;
}
}
+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 ())
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;
}
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 ());
}
}