Only decommit parts of regions and the mark array when memory is low. (#56730)
authorPeter Sollich <petersol@microsoft.com>
Wed, 4 Aug 2021 12:47:03 +0000 (14:47 +0200)
committerGitHub <noreply@github.com>
Wed, 4 Aug 2021 12:47:03 +0000 (14:47 +0200)
We'll decommit completely free regions if they exceed the budget, but as we'll use the available memory in regions *not* on the free list preferentially, it seems smarter to decommit the tail ends of these regions only when memory is low.

In a simple GCPerfSim Scenario (-tc 10 -tagb 1000 -tlgb 1 on a 10-core box) this made about a 10% difference in run time, the time saved is mainly in the OS - VirtualFree, VirtualAlloc, and KiPageFault.

src/coreclr/gc/gc.cpp

index 9c8acf3..07d5df2 100644 (file)
@@ -10873,7 +10873,11 @@ void gc_heap::clear_region_info (heap_segment* region)
     ::record_changed_seg ((uint8_t*)region, heap_segment_reserved (region),
                         settings.gc_index, current_bgc_state,
                         seg_deleted);
-    decommit_mark_array_by_seg (region);
+
+    if (settings.entry_memory_load >= high_memory_load_th || g_low_memory_status)
+    {
+        decommit_mark_array_by_seg (region);
+    }
 #endif //BACKGROUND_GC
 }
 
@@ -11358,6 +11362,12 @@ void gc_heap::decommit_heap_segment_pages (heap_segment* seg,
 size_t gc_heap::decommit_heap_segment_pages_worker (heap_segment* seg,
                                                     uint8_t* new_committed)
 {
+#ifdef USE_REGIONS
+    if (settings.entry_memory_load < high_memory_load_th && !g_low_memory_status)
+    {
+        return 0;
+    }
+#endif
     assert (!use_large_pages_p);
     uint8_t* page_start = align_on_page (new_committed);
     size_t size = heap_segment_committed (seg) - page_start;
@@ -11387,6 +11397,13 @@ size_t gc_heap::decommit_heap_segment_pages_worker (heap_segment* seg,
 //decommit all pages except one or 2
 void gc_heap::decommit_heap_segment (heap_segment* seg)
 {
+#ifdef USE_REGIONS
+    if (settings.entry_memory_load < high_memory_load_th && !g_low_memory_status)
+    {
+        return;
+    }
+#endif
+
     uint8_t*  page_start = align_on_page (heap_segment_mem (seg));
 
     dprintf (3, ("Decommitting heap segment %Ix(%Ix)", (size_t)seg, heap_segment_mem (seg)));