/**/
static mword allocated_heap;
static mword total_alloc = 0;
+static mword total_alloc_max = 0;
/* GC triggers. */
static mword sgen_memgov_available_free_space (void);
-static mword
-double_to_mword_with_saturation (double value)
-{
- if (value >= (double)MWORD_MAX_VALUE)
- return MWORD_MAX_VALUE;
- return (mword)value;
-}
-
/* GC trigger heuristics. */
static void
sgen_memgov_try_calculate_minor_collection_allowance (gboolean overwrite)
{
- size_t num_major_sections, num_major_sections_saved;
- mword los_memory_saved, new_major, new_heap_size, save_target, allowance_target;
+ size_t num_major_sections;
+ mword new_major, new_heap_size, allowance_target;
if (overwrite)
g_assert (need_calculate_minor_collection_allowance);
if (!need_calculate_minor_collection_allowance)
return;
- if (!*major_collector.have_swept) {
+ if (!major_collector.have_finished_sweeping ()) {
if (overwrite)
minor_collection_allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
return;
num_major_sections = major_collector.get_num_major_sections ();
- num_major_sections_saved = MAX (last_collection_old_num_major_sections - num_major_sections, 0);
- los_memory_saved = MAX (last_collection_old_los_memory_usage - last_collection_los_memory_usage, 1);
-
new_major = num_major_sections * major_collector.section_size;
new_heap_size = new_major + last_collection_los_memory_usage;
- save_target = (mword)((new_major + last_collection_los_memory_usage) * SGEN_DEFAULT_SAVE_TARGET_RATIO);
-
/*
- * We aim to allow the allocation of as many sections as is
- * necessary to reclaim save_target sections in the next
- * collection. We assume the collection pattern won't change.
- * In the last cycle, we had num_major_sections_saved for
- * minor_collection_sections_alloced. Assuming things won't
- * change, this must be the same ratio as save_target for
- * allowance_target, i.e.
- *
- * num_major_sections_saved save_target
- * --------------------------------- == ----------------
- * minor_collection_sections_alloced allowance_target
- *
- * hence:
+ * We allow the heap to grow by one third its current size before we start the next
+ * major collection.
*/
- allowance_target = double_to_mword_with_saturation ((double)save_target * (double)(minor_collection_sections_alloced * major_collector.section_size + last_collection_los_memory_alloced) / (double)(num_major_sections_saved * major_collector.section_size + los_memory_saved));
+ allowance_target = new_heap_size / 3;
- minor_collection_allowance = MAX (MIN (allowance_target, num_major_sections * major_collector.section_size + los_memory_usage), MIN_MINOR_COLLECTION_ALLOWANCE);
+ minor_collection_allowance = MAX (allowance_target, MIN_MINOR_COLLECTION_ALLOWANCE);
if (new_heap_size + minor_collection_allowance > soft_heap_limit) {
if (new_heap_size > soft_heap_limit)
SGEN_LOG (1, "Allowance: %ld bytes", (long)minor_collection_allowance);
}
- if (major_collector.have_computed_minor_collection_allowance)
- major_collector.have_computed_minor_collection_allowance ();
+ if (major_collector.free_swept_blocks)
+ major_collector.free_swept_blocks ();
need_calculate_minor_collection_allowance = FALSE;
}
SGEN_ATOMIC_ADD_P (total_alloc, size);
if (flags & SGEN_ALLOC_HEAP)
MONO_GC_HEAP_ALLOC ((mword)ptr, size);
+ total_alloc_max = MAX (total_alloc_max, total_alloc);
}
return ptr;
}
SGEN_ATOMIC_ADD_P (total_alloc, size);
if (flags & SGEN_ALLOC_HEAP)
MONO_GC_HEAP_ALLOC ((mword)ptr, size);
+ total_alloc_max = MAX (total_alloc_max, total_alloc);
}
return ptr;
}
SGEN_ATOMIC_ADD_P (total_alloc, -(gssize)size);
if (flags & SGEN_ALLOC_HEAP)
MONO_GC_HEAP_FREE ((mword)addr, size);
+ total_alloc_max = MAX (total_alloc_max, total_alloc);
}
int64_t
gboolean
sgen_memgov_try_alloc_space (mword size, int space)
{
- if (sgen_memgov_available_free_space () < size)
+ if (sgen_memgov_available_free_space () < size) {
+ SGEN_ASSERT (4, !sgen_is_worker_thread (mono_native_thread_id_get ()), "Memory shouldn't run out in worker thread");
return FALSE;
+ }
SGEN_ATOMIC_ADD_P (allocated_heap, size);
mono_runtime_resource_check_limit (MONO_RESOURCE_GC_HEAP, allocated_heap);
debug_print_allowance = debug_allowance;
minor_collection_allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
+ mono_counters_register ("Memgov alloc", MONO_COUNTER_GC | MONO_COUNTER_WORD | MONO_COUNTER_BYTES | MONO_COUNTER_VARIABLE, &total_alloc);
+ mono_counters_register ("Memgov max alloc", MONO_COUNTER_GC | MONO_COUNTER_WORD | MONO_COUNTER_BYTES | MONO_COUNTER_MONOTONIC, &total_alloc_max);
+
if (max_heap == 0)
return;