From 78d8ce7e4395b9cff4de99d2c8fbc23f322fd70a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 5 Oct 2022 10:57:46 -0700 Subject: [PATCH] [release/7.0] fix lower heap hard limit condition for regions (#76588) * fix lower heap hard limit condition for regions * adjust region sizes based on individual heap sizes * updated comment * more tuning * on more tuning update. * fixing the case for per heap hard_limit and some styling changes. * CR updates * small refactor oversight from the main PR. Co-authored-by: Manish Godse <61718172+mangod9@users.noreply.github.com> --- src/coreclr/gc/gc.cpp | 38 ++++++++++++++++++++++++++++++++++++-- src/coreclr/gc/gcconfig.h | 2 +- src/coreclr/gc/gcpriv.h | 2 ++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index d603eda9ef2b0..0f6318ba8f8cf 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -44895,10 +44895,20 @@ HRESULT GCHeap::Initialize() { if (gc_heap::heap_hard_limit) { - gc_heap::regions_range = 2 * gc_heap::heap_hard_limit; + if (gc_heap::heap_hard_limit_oh[soh]) + { + gc_heap::regions_range = gc_heap::heap_hard_limit; + } + else + { + // We use this calculation because it's close to what we used for segments. + gc_heap::regions_range = ((gc_heap::use_large_pages_p) ? (2 * gc_heap::heap_hard_limit) + : (5 * gc_heap::heap_hard_limit)); + } } else { + // If no hard_limit is configured the reservation size is max of 256gb or 2x physical limit gc_heap::regions_range = max(((size_t)256 * 1024 * 1024 * 1024), (size_t)(2 * gc_heap::total_physical_mem)); } gc_heap::regions_range = align_on_page(gc_heap::regions_range); @@ -45049,7 +45059,31 @@ HRESULT GCHeap::Initialize() #ifdef USE_REGIONS gc_heap::enable_special_regions_p = (bool)GCConfig::GetGCEnableSpecialRegions(); size_t gc_region_size = (size_t)GCConfig::GetGCRegionSize(); - if (!power_of_two_p(gc_region_size) || ((gc_region_size * nhp * 19) > gc_heap::regions_range)) + + // Adjust GCRegionSize based on how large each heap would be, for smaller heaps we would + // like to keep Region sizes small. We choose between 4, 2 and 1mb based on the calculations + // below (unless its configured explictly) such that there are at least 2 regions available + // except for the smallest case. Now the lowest limit possible is 4mb. + if (gc_region_size == 0) + { + // We have a minimum amount of basic regions we have to fit per heap, and we'd like to have the initial + // regions only take up half of the space. + size_t max_region_size = gc_heap::regions_range / 2 / nhp / min_regions_per_heap; + if (max_region_size >= (4 * 1024 * 1024)) + { + gc_region_size = 4 * 1024 * 1024; + } + else if (max_region_size >= (2 * 1024 * 1024)) + { + gc_region_size = 2 * 1024 * 1024; + } + else + { + gc_region_size = 1 * 1024 * 1024; + } + } + + if (!power_of_two_p(gc_region_size) || ((gc_region_size * nhp * min_regions_per_heap) > gc_heap::regions_range)) { return E_OUTOFMEMORY; } diff --git a/src/coreclr/gc/gcconfig.h b/src/coreclr/gc/gcconfig.h index 532a6998c0bc6..2b5f87b41f4cc 100644 --- a/src/coreclr/gc/gcconfig.h +++ b/src/coreclr/gc/gcconfig.h @@ -104,7 +104,7 @@ class GCConfigStringHolder INT_CONFIG (GCHeapHardLimitPercent, "GCHeapHardLimitPercent", "System.GC.HeapHardLimitPercent", 0, "Specifies the GC heap usage as a percentage of the total memory") \ INT_CONFIG (GCTotalPhysicalMemory, "GCTotalPhysicalMemory", NULL, 0, "Specifies what the GC should consider to be total physical memory") \ INT_CONFIG (GCRegionRange, "GCRegionRange", NULL, 0, "Specifies the range for the GC heap") \ - INT_CONFIG (GCRegionSize, "GCRegionSize", NULL, 4194304, "Specifies the size for a basic GC region") \ + INT_CONFIG (GCRegionSize, "GCRegionSize", NULL, 0, "Specifies the size for a basic GC region") \ INT_CONFIG (GCEnableSpecialRegions, "GCEnableSpecialRegions", NULL, 0, "Specifies to enable special handling some regions like SIP") \ STRING_CONFIG(LogFile, "GCLogFile", NULL, "Specifies the name of the GC log file") \ STRING_CONFIG(ConfigLogFile, "GCConfigLogFile", NULL, "Specifies the name of the GC config log file") \ diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index 45f266259c62d..084fa0ba925d5 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -5807,6 +5807,8 @@ class heap_segment #define region_alloc_free_bit (1 << (sizeof (uint32_t) * 8 - 1)) +const int min_regions_per_heap = ((ephemeral_generation_count + 1) + ((total_generation_count - uoh_start_generation) * LARGE_REGION_FACTOR)); + enum allocate_direction { allocate_forward = 1,