* Bigger values increases throughput by allowing more garbage to sit in the major heap.
* Smaller values leads to better memory effiency but more frequent major collections.
*/
-#define SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO 4
+#define SGEN_DEFAULT_ALLOWANCE_NURSERY_SIZE_RATIO 4.0
+
+#define SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO 1.0
+#define SGEN_MAX_ALLOWANCE_NURSERY_SIZE_RATIO 10.0
/*
* Default ratio of memory we want to release in a major collection in relation to the the current heap size.
* sizes as they will use a small fraction only.
*
*/
-#define SGEN_DEFAULT_SAVE_TARGET_RATIO 0.5f
+#define SGEN_DEFAULT_SAVE_TARGET_RATIO 0.5
+
+#define SGEN_MIN_SAVE_TARGET_RATIO 0.1
+#define SGEN_MAX_SAVE_TARGET_RATIO 2.0
#endif
int result;
int dummy;
gboolean debug_print_allowance = FALSE;
+ double allowance_ratio = 0, save_target = 0;
do {
result = InterlockedCompareExchange (&gc_initialized, -1, 0);
continue;
}
#endif
+ if (g_str_has_prefix (opt, "save-target-ratio=")) {
+ char *endptr;
+ opt = strchr (opt, '=') + 1;
+ save_target = strtod (opt, &endptr);
+ if (endptr == opt) {
+ fprintf (stderr, "save-target-ratio must be a number.");
+ exit (1);
+ }
+ if (save_target < SGEN_MIN_SAVE_TARGET_RATIO || save_target > SGEN_MAX_SAVE_TARGET_RATIO) {
+ fprintf (stderr, "save-target-ratio must be between %.2f - %.2f.", SGEN_MIN_SAVE_TARGET_RATIO, SGEN_MAX_SAVE_TARGET_RATIO);
+ exit (1);
+ }
+ continue;
+ }
+ if (g_str_has_prefix (opt, "default-allowance-ratio=")) {
+ char *endptr;
+ opt = strchr (opt, '=') + 1;
+
+ allowance_ratio = strtod (opt, &endptr);
+ if (endptr == opt) {
+ fprintf (stderr, "save-target-ratio must be a number.");
+ exit (1);
+ }
+ if (allowance_ratio < SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO || allowance_ratio > SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO) {
+ fprintf (stderr, "default-allowance-ratio must be between %.2f - %.2f.", SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO, SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO);
+ exit (1);
+ }
+ continue;
+ }
+
if (major_collector.handle_gc_param && major_collector.handle_gc_param (opt))
continue;
major_collector.print_gc_param_usage ();
if (sgen_minor_collector.print_gc_param_usage)
sgen_minor_collector.print_gc_param_usage ();
+ fprintf (stderr, " Experimental options:\n");
+ fprintf (stderr, " save-target-ratio=R (where R must be between %.2f - %.2f).\n", SGEN_MIN_SAVE_TARGET_RATIO, SGEN_MAX_SAVE_TARGET_RATIO);
+ fprintf (stderr, " default-allowance-ratio=R (where R must be between %.2f - %.2f).\n", SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO, SGEN_MAX_ALLOWANCE_NURSERY_SIZE_RATIO);
exit (1);
}
g_strfreev (opts);
if (major_collector.post_param_init)
major_collector.post_param_init ();
- sgen_memgov_init (max_heap, soft_limit, debug_print_allowance);
+ sgen_memgov_init (max_heap, soft_limit, debug_print_allowance, allowance_ratio, save_target);
memset (&remset, 0, sizeof (remset));
#include "utils/mono-mmap.h"
#include "utils/mono-logger-internal.h"
-#define MIN_MINOR_COLLECTION_ALLOWANCE ((mword)(DEFAULT_NURSERY_SIZE * SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO))
+#define MIN_MINOR_COLLECTION_ALLOWANCE ((mword)(DEFAULT_NURSERY_SIZE * default_allowance_nursery_size_ratio))
-/*heap limits*/
+/*Heap limits and allocation knobs*/
static mword max_heap_size = ((mword)0)- ((mword)1);
static mword soft_heap_limit = ((mword)0) - ((mword)1);
-static mword allocated_heap;
-/*Memory usage tracking */
+static double default_allowance_nursery_size_ratio = SGEN_DEFAULT_ALLOWANCE_NURSERY_SIZE_RATIO;
+static double save_target_ratio = SGEN_DEFAULT_SAVE_TARGET_RATIO;
+
+/**/
+static mword allocated_heap;
static mword total_alloc = 0;
/* GC triggers. */
+static gboolean debug_print_allowance = FALSE;
+
+
/* use this to tune when to do a major/minor collection */
static mword memory_pressure = 0;
static mword minor_collection_allowance;
static int minor_collection_sections_alloced = 0;
-static gboolean debug_print_allowance = FALSE;
-
-/* GC stats */
static int last_major_num_sections = 0;
static int last_los_memory_usage = 0;
static gboolean major_collection_happened = FALSE;
}
void
-sgen_memgov_init (glong max_heap, glong soft_limit, gboolean debug_allowance)
+sgen_memgov_init (glong max_heap, glong soft_limit, gboolean debug_allowance, double allowance_ratio, double save_target)
{
if (soft_limit)
soft_heap_limit = soft_limit;
max_heap_size = max_heap - sgen_nursery_size;
minor_collection_allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
+
+ if (allowance_ratio)
+ default_allowance_nursery_size_ratio = allowance_ratio;
+
+ if (save_target)
+ save_target_ratio = save_target;
}
#endif
#define __MONO_SGEN_MEMORY_GOVERNOR_H__
/* Heap limits */
-void sgen_memgov_init (glong max_heap, glong soft_limit, gboolean debug_allowance) MONO_INTERNAL;
+void sgen_memgov_init (glong max_heap, glong soft_limit, gboolean debug_allowance, double min_allowance_ratio, double save_target) MONO_INTERNAL;
void sgen_memgov_release_space (mword size, int space) MONO_INTERNAL;
gboolean sgen_memgov_try_alloc_space (mword size, int space) MONO_INTERNAL;