From db141cfc0ac4e8ca37c823749c24e5acbe128e80 Mon Sep 17 00:00:00 2001 From: Peter Bex Date: Sun, 1 Dec 2019 15:36:36 +0100 Subject: [PATCH] Improve heap shrinkage factor. The old calculation was confused because it took a percentage of a percentage. This adds a new option to set heap shrinkage watermark and uses that as-is to decide when to change the heap size. By default, the heap will be shrunk by 50% when the used amount is at 25% of the heap. This looks closest to what seems to be the intended behaviour of the code, and is also what was suggested in #1379 by Sven Hartrumpf. --- NEWS | 3 +++ manual/Using the compiler | 8 +++++--- runtime.c | 12 ++++++++++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 0890e8fd..05b4dfe9 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,9 @@ an error instead of hanging forever (fixes #1586). - define-record-type will now give an error if the constructor definition refers to field that's not listed elsewhere (see #1633) + - Added new -:hu option to set the memory usage low watermark + percentage at which the heap should be shrunk, and changed the + calculation to actually reflect this (see #1379). - Compiler - Fixed a bug in lfa2 pass which caused "if" or "cond" nodes to be diff --git a/manual/Using the compiler b/manual/Using the compiler index da9f1808..9b096153 100644 --- a/manual/Using the compiler +++ b/manual/Using the compiler @@ -219,11 +219,13 @@ by the startup code and will not be contained in the result of ; {{-:hgPERCENTAGE}} : Sets the growth rate of the heap in percent. If the heap is exhausted, then it will grow by {{PERCENTAGE}}. The default is 200. -; {{-:hiNUMBER}} : Specifies the initial heap size +; {{-:hiNUMBER}} : Specifies the initial heap size (this number includes both heap semispaces, therefore only half of it is actually available to the program). -; {{-:hmNUMBER}} : Specifies a maximal heap size. The default is (2GB - 15). +; {{-:hmNUMBER}} : Specifies a maximal heap size (including both semispaces). The default is (2GB - 15). -; {{-:hsPERCENTAGE}} : Sets the shrink rate of the heap in percent. If no more than a quarter of {{PERCENTAGE}} of the heap is used, then it will shrink to {{PERCENTAGE}}. The default is 50. Note: If you want to make sure that the heap never shrinks, specify a value of {{0}}. (this can be useful in situations where an optimal heap-size is known in advance). +; {{-:hsPERCENTAGE}} : Sets the shrink rate of the heap in percent. The heap is shrunk to {{PERCENTAGE}} when the watermark is reached. The default is 50. Note: If you want to make sure that the heap never shrinks, specify a value of {{0}}. (this can be useful in situations where an optimal heap-size is known in advance). + +; {{-:huPERCENTAGE}} : Sets the memory usage watermark below which heap shrinking is triggered. The default is 25. ; {{-:o}} : Disables detection of stack overflows at run-time. diff --git a/runtime.c b/runtime.c index a3cffeb6..4a190df5 100644 --- a/runtime.c +++ b/runtime.c @@ -358,7 +358,8 @@ C_TLS int C_main_argc; C_TLS C_uword C_heap_growth, - C_heap_shrinkage; + C_heap_shrinkage, + C_heap_shrinkage_used; C_TLS C_uword C_maximal_heap_size; C_TLS time_t C_startup_time_seconds, @@ -782,6 +783,8 @@ int CHICKEN_initialize(int heap, int stack, int symbols, void *toplevel) if(C_heap_shrinkage <= 0) C_heap_shrinkage = DEFAULT_HEAP_SHRINKAGE; + if(C_heap_shrinkage_used <= 0) C_heap_shrinkage_used = DEFAULT_HEAP_SHRINKAGE_USED; + if(C_maximal_heap_size <= 0) C_maximal_heap_size = DEFAULT_MAXIMAL_HEAP_SIZE; #if !defined(NO_DLOAD2) && defined(HAVE_DLFCN_H) @@ -1370,6 +1373,7 @@ void CHICKEN_parse_command_line(int argc, char *argv[], C_word *heap, C_word *st " -:hmSIZE set maximal heap size\n" " -:hgPERCENTAGE set heap growth percentage\n" " -:hsPERCENTAGE set heap shrink percentage\n" + " -:huPERCENTAGE set percentage of memory used at which heap will be shrunk\n" " -:hSIZE set fixed heap size\n" " -:r write trace output to stderr\n" " -:p collect statistical profile and write to file at exit\n" @@ -1404,6 +1408,9 @@ void CHICKEN_parse_command_line(int argc, char *argv[], C_word *heap, C_word *st case 's': C_heap_shrinkage = arg_val(ptr + 1); goto next; + case 'u': + C_heap_shrinkage_used = arg_val(ptr + 1); + goto next; default: *heap = arg_val(ptr); heap_size_changed = 1; @@ -3605,8 +3612,9 @@ C_regparm void C_fcall C_reclaim(void *trampoline, C_word c) count = (C_uword)tospace_top - (C_uword)tospace_start; /*** isn't gc_mode always GC_MAJOR here? */ + /* NOTE: count is actual usage, heap_size is both halves */ if(gc_mode == GC_MAJOR && - count < percentage(percentage(heap_size, C_heap_shrinkage), DEFAULT_HEAP_SHRINKAGE_USED) && + count < percentage(heap_size/2, C_heap_shrinkage_used) && heap_size > MINIMAL_HEAP_SIZE && !C_heap_size_is_fixed) C_rereclaim2(percentage(heap_size, C_heap_shrinkage), 0); else { -- 2.20.1