fix lower heap hard limit condition for regions (#76407)
authorManish Godse <61718172+mangod9@users.noreply.github.com>
Tue, 4 Oct 2022 05:07:52 +0000 (22:07 -0700)
committerGitHub <noreply@github.com>
Tue, 4 Oct 2022 05:07:52 +0000 (22:07 -0700)
* 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

src/coreclr/gc/gc.cpp
src/coreclr/gc/gcconfig.h
src/coreclr/gc/gcpriv.h

index adccf6d..07a45f9 100644 (file)
@@ -44906,10 +44906,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);
@@ -45056,7 +45066,30 @@ 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.
+        if ((gc_heap::regions_range / nhp / min_regions_per_heap) / 2 >= (4 * 1024 * 1024))
+        {
+            gc_region_size = 4 * 1024 * 1024;
+        }
+        else if ((gc_heap::regions_range / nhp / min_regions_per_heap) / 2 >= (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;
     }
index 532a699..2b5f87b 100644 (file)
@@ -104,7 +104,7 @@ public:
     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")                                           \
index df4ce12..37e69af 100644 (file)
@@ -5807,6 +5807,8 @@ public:
 
 #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,