From: Andi Kleen <a...@linux.intel.com> Add a threshold to avoid freeing pages back too early to the OS. This avoid virtual memory map fragmentation.
Based on a idea from Honza ggc/doc/: 2011-10-08 Andi Kleen <a...@linux.intel.com> PR other/50636 * invoke.texi (ggc-free-threshold, ggc-free-min): Add. ggc/: 2011-10-08 Andi Kleen <a...@linux.intel.com> PR other/50636 * ggc-page.c (ggc_collect): Add free threshold. * params.def (GGC_FREE_THRESHOLD, GGC_FREE_MIN): Add. --- gcc/doc/invoke.texi | 11 +++++++++++ gcc/ggc-page.c | 13 +++++++++---- gcc/params.def | 10 ++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index ef7ac68..6557f66 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -8837,6 +8837,17 @@ very large effectively disables garbage collection. Setting this parameter and @option{ggc-min-expand} to zero causes a full collection to occur at every opportunity. +@item ggc-free-threshold + +Only free memory back to the system when it would free more than this +many percent of the total allocated memory. Default is 20 percent. +This avoids memory fragmentation. + +@item ggc-free-min + +Only free memory back to the system when it would free more than this. +Unit is kilobytes. + @item max-reload-search-insns The maximum number of instruction reload should look backward for equivalent register. Increasing values mean more aggressive optimization, making the diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c index 6e08cda..cd1c41a 100644 --- a/gcc/ggc-page.c +++ b/gcc/ggc-page.c @@ -1968,14 +1968,19 @@ ggc_collect (void) if (GGC_DEBUG_LEVEL >= 2) fprintf (G.debug_file, "BEGIN COLLECTING\n"); + /* Release the pages we freed the last time we collected, but didn't + reuse in the interim. But only do this if this would free a + reasonable number of pages. Otherwise hold on to them + to avoid virtual memory fragmentation. */ + if (G.bytes_mapped - G.allocated >= + (PARAM_VALUE (GGC_FREE_THRESHOLD) / 100.0) * G.bytes_mapped && + G.bytes_mapped - G.allocated >= (size_t)PARAM_VALUE (GGC_FREE_MIN) * 1024) + release_pages (); + /* Zero the total allocated bytes. This will be recalculated in the sweep phase. */ G.allocated = 0; - /* Release the pages we freed the last time we collected, but didn't - reuse in the interim. */ - release_pages (); - /* Indicate that we've seen collections at this context depth. */ G.context_depth_collections = ((unsigned long)1 << (G.context_depth + 1)) - 1; diff --git a/gcc/params.def b/gcc/params.def index 5e49c48..ca28715 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -561,6 +561,16 @@ DEFPARAM(GGC_MIN_HEAPSIZE, #undef GGC_MIN_EXPAND_DEFAULT #undef GGC_MIN_HEAPSIZE_DEFAULT +DEFPARAM(GGC_FREE_THRESHOLD, + "ggc-free-threshold", + "Dont free memory back to system less this percent of the total memory", + 20, 0, 100) + +DEFPARAM(GGC_FREE_MIN, + "ggc-free-min", + "Dont free less memory than this back to the system, in kilobytes", + 8 * 1024, 0, 0) + DEFPARAM(PARAM_MAX_RELOAD_SEARCH_INSNS, "max-reload-search-insns", "The maximum number of instructions to search backward when looking for equivalent reload", -- 1.7.5.4