Skip to content

Commit

Permalink
Cleaned up version of earlier PR #48601.
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterSolMS authored and github-actions committed Sep 2, 2021
1 parent 1b47dd9 commit bd7b8e5
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 24 deletions.
118 changes: 94 additions & 24 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2243,6 +2243,7 @@ double gc_heap::short_plugs_pad_ratio = 0;
#endif //SHORT_PLUGS

int gc_heap::generation_skip_ratio_threshold = 0;
int gc_heap::conserve_mem_setting = 0;

uint64_t gc_heap::suspended_start_time = 0;
uint64_t gc_heap::end_gc_time = 0;
Expand Down Expand Up @@ -3103,17 +3104,20 @@ gc_heap::dt_high_frag_p (gc_tuning_point tp,
}
else
{
#ifndef MULTIPLE_HEAPS
if (gen_number == max_generation)
{
float frag_ratio = (float)(dd_fragmentation (dynamic_data_of (max_generation))) / (float)generation_size (max_generation);
if (frag_ratio > 0.65)
float frag_limit = 1.0f - conserve_mem_setting / 10.0f;
#ifndef MULTIPLE_HEAPS
if (conserve_mem_setting == 0)
frag_limit = 0.65f;
#endif //!MULTIPLE_HEAPS
if (frag_ratio > frag_limit)
{
dprintf (GTC_LOG, ("g2 FR: %d%%", (int)(frag_ratio*100)));
return TRUE;
}
}
#endif //!MULTIPLE_HEAPS
size_t fr = generation_unusable_fragmentation (generation_of (gen_number));
ret = (fr > dd_fragmentation_limit(dd));
if (ret)
Expand Down Expand Up @@ -12361,9 +12365,9 @@ void gc_heap::make_generation (int gen_num, heap_segment* seg, uint8_t* start)
#endif //DOUBLY_LINKED_FL

#ifdef FREE_USAGE_STATS
memset (gen->gen_free_spaces, 0, sizeof (gen.gen_free_spaces));
memset (gen->gen_current_pinned_free_spaces, 0, sizeof (gen.gen_current_pinned_free_spaces));
memset (gen->gen_plugs, 0, sizeof (gen.gen_plugs));
memset (gen->gen_free_spaces, 0, sizeof (gen->gen_free_spaces));
memset (gen->gen_current_pinned_free_spaces, 0, sizeof (gen->gen_current_pinned_free_spaces));
memset (gen->gen_plugs, 0, sizeof (gen->gen_plugs));
#endif //FREE_USAGE_STATS
}

Expand Down Expand Up @@ -12958,6 +12962,14 @@ gc_heap::init_semi_shared()
#endif //FEATURE_LOH_COMPACTION
#endif //FEATURE_EVENT_TRACE

conserve_mem_setting = (int)GCConfig::GetGCConserveMem();
if (conserve_mem_setting < 0)
conserve_mem_setting = 0;
if (conserve_mem_setting > 9)
conserve_mem_setting = 9;

dprintf (1, ("conserve_mem_setting = %d", conserve_mem_setting));

ret = 1;

cleanup:
Expand Down Expand Up @@ -17477,7 +17489,6 @@ void gc_heap::init_free_and_plug()
#else
memset (gen->gen_free_spaces, 0, sizeof (gen->gen_free_spaces));
#endif //DOUBLY_LINKED_FL
memset (gen->gen_plugs_allocated_in_free, 0, sizeof (gen->gen_plugs_allocated_in_free));
memset (gen->gen_plugs, 0, sizeof (gen->gen_plugs));
memset (gen->gen_current_pinned_free_spaces, 0, sizeof (gen->gen_current_pinned_free_spaces));
}
Expand All @@ -17495,7 +17506,7 @@ void gc_heap::init_free_and_plug()

void gc_heap::print_free_and_plug (const char* msg)
{
#if defined(FREE_USAGE_STATS) && defined(SIMPLE_DPRINTF)
#ifdef FREE_USAGE_STATS
int older_gen = ((settings.condemned_generation == max_generation) ? max_generation : (settings.condemned_generation + 1));
for (int i = 0; i <= older_gen; i++)
{
Expand All @@ -17516,7 +17527,7 @@ void gc_heap::print_free_and_plug (const char* msg)
}
#else
UNREFERENCED_PARAMETER(msg);
#endif //FREE_USAGE_STATS && SIMPLE_DPRINTF
#endif //FREE_USAGE_STATS
}

// replace with allocator::first_suitable_bucket
Expand Down Expand Up @@ -17588,8 +17599,8 @@ void gc_heap::add_gen_free (int gen_number, size_t free_size)
(gen->gen_free_spaces[i])++;
if (gen_number == max_generation)
{
dprintf (3, ("Mb b%d: f+ %Id (%Id->%Id)",
i, free_size, (gen->gen_free_spaces[i]).num_items, (gen->gen_free_spaces[i]).total_size));
dprintf (3, ("Mb b%d: f+ %Id (%Id)",
i, free_size, gen->gen_free_spaces[i]));
}
#else
UNREFERENCED_PARAMETER(gen_number);
Expand All @@ -17611,8 +17622,8 @@ void gc_heap::remove_gen_free (int gen_number, size_t free_size)
(gen->gen_free_spaces[i])--;
if (gen_number == max_generation)
{
dprintf (3, ("Mb b%d: f- %Id (%Id->%Id)",
i, free_size, (gen->gen_free_spaces[i]).num_items, (gen->gen_free_spaces[i]).total_size));
dprintf (3, ("Mb b%d: f- %Id (%Id)",
i, free_size, gen->gen_free_spaces[i]));
}
#else
UNREFERENCED_PARAMETER(gen_number);
Expand Down Expand Up @@ -18777,26 +18788,28 @@ int gc_heap::joined_generation_to_condemn (BOOL should_evaluate_elevation,
}
else if ((current_total_committed * 10) >= (heap_hard_limit * 9))
{
size_t loh_frag = get_total_gen_fragmentation (loh_generation);
size_t combined_frag = get_total_gen_fragmentation (max_generation) +
get_total_gen_fragmentation (loh_generation);

// If the LOH frag is >= 1/8 it's worth compacting it
if ((loh_frag * 8) >= heap_hard_limit)
// If the combined frag is >= 1/8 it's worth compacting
if ((combined_frag * 8) >= heap_hard_limit)
{
dprintf (GTC_LOG, ("loh frag: %Id > 1/8 of limit %Id", loh_frag, (heap_hard_limit / 8)));
dprintf (GTC_LOG, ("gen2+loh frag: %Id > 1/8 of limit %Id", combined_frag, (heap_hard_limit / 8)));
gc_data_global.gen_to_condemn_reasons.set_condition(gen_joined_limit_loh_frag);
full_compact_gc_p = true;
}
else
{
// If there's not much fragmentation but it looks like it'll be productive to
// collect LOH, do that.
size_t est_loh_reclaim = get_total_gen_estimated_reclaim (loh_generation);
if ((est_loh_reclaim * 8) >= heap_hard_limit)
// collect, do that.
size_t est_combined_reclaim = get_total_gen_estimated_reclaim (max_generation) +
get_total_gen_estimated_reclaim (loh_generation);
if ((est_combined_reclaim * 8) >= heap_hard_limit)
{
gc_data_global.gen_to_condemn_reasons.set_condition(gen_joined_limit_loh_reclaim);
gc_data_global.gen_to_condemn_reasons.set_condition (gen_joined_limit_loh_reclaim);
full_compact_gc_p = true;
}
dprintf (GTC_LOG, ("loh est reclaim: %Id, 1/8 of limit %Id", est_loh_reclaim, (heap_hard_limit / 8)));
dprintf (GTC_LOG, ("gen2+loh est reclaim: %Id, 1/8 of limit %Id", est_combined_reclaim, (heap_hard_limit / 8)));
}
}

Expand All @@ -18805,7 +18818,38 @@ int gc_heap::joined_generation_to_condemn (BOOL should_evaluate_elevation,
n = max_generation;
*blocking_collection_p = TRUE;
settings.loh_compaction = TRUE;
dprintf (GTC_LOG, ("compacting LOH due to hard limit"));
dprintf (GTC_LOG, ("compacting gen2+loh due to hard limit"));
}
}

if ((conserve_mem_setting != 0) && (n >= max_generation))
{
float frag_limit = 1.0f - conserve_mem_setting / 10.0f;

size_t loh_size = get_total_gen_size (loh_generation);
size_t gen2_size = get_total_gen_size (max_generation);
float loh_frag_ratio = 0.0f;
float combined_frag_ratio = 0.0f;
if (loh_size != 0)
{
size_t loh_frag = get_total_gen_fragmentation (loh_generation);
size_t gen2_frag = get_total_gen_fragmentation (max_generation);
loh_frag_ratio = (float)loh_frag / (float)loh_size;
combined_frag_ratio = (float)(gen2_frag + loh_frag) / (float)(gen2_size + loh_size);
}
if (combined_frag_ratio > frag_limit)
{
dprintf (GTC_LOG, ("combined frag: %f > limit %f, loh frag: %f", combined_frag_ratio, frag_limit, loh_frag_ratio));
gc_data_global.gen_to_condemn_reasons.set_condition (gen_max_high_frag_p);

n = max_generation;
*blocking_collection_p = TRUE;
if (loh_frag_ratio > frag_limit)
{
settings.loh_compaction = TRUE;

dprintf (GTC_LOG, ("compacting LOH due to GCConserveMem setting"));
}
}
}

Expand Down Expand Up @@ -23967,6 +24011,21 @@ size_t gc_heap::get_total_gen_estimated_reclaim (int gen_number)
return total_estimated_reclaim;
}

size_t gc_heap::get_total_gen_size (int gen_number)
{
#ifdef MULTIPLE_HEAPS
size_t size = 0;
for (int hn = 0; hn < gc_heap::n_heaps; hn++)
{
gc_heap* hp = gc_heap::g_heaps[hn];
size += hp->generation_sizes (hp->generation_of (gen_number));
}
#else
size_t size = generation_sizes (generation_of (gen_number));
#endif //MULTIPLE_HEAPS
return size;
}

size_t gc_heap::committed_size()
{
size_t total_committed = 0;
Expand Down Expand Up @@ -26128,7 +26187,7 @@ BOOL gc_heap::plan_loh()

void gc_heap::compact_loh()
{
assert (loh_compaction_requested() || heap_hard_limit);
assert (loh_compaction_requested() || heap_hard_limit || conserve_mem_setting);

#ifdef FEATURE_EVENT_TRACE
uint64_t start_time, end_time;
Expand Down Expand Up @@ -37909,6 +37968,16 @@ size_t gc_heap::desired_new_allocation (dynamic_data* dd,
cst = min (1.0f, float (out) / float (dd_begin_data_size (dd)));

f = surv_to_growth (cst, limit, max_limit);
if (conserve_mem_setting != 0)
{
// if this is set, compute a growth factor based on it.
// formula below means use 50% of the allowable fragmentation
float f_conserve = (10.0f / conserve_mem_setting - 1) * 0.5f + 1.0f;

// use the smaller one
f = min (f, f_conserve);
}

size_t max_growth_size = (size_t)(max_size / f);
if (current_size >= max_growth_size)
{
Expand All @@ -37932,6 +38001,7 @@ size_t gc_heap::desired_new_allocation (dynamic_data* dd,
#ifdef BGC_SERVO_TUNING
!bgc_tuning::fl_tuning_triggered &&
#endif //BGC_SERVO_TUNING
(conserve_mem_setting == 0) &&
(dd_fragmentation (dd) > ((size_t)((f-1)*current_size))))
{
//reducing allocation in case of fragmentation
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/gc/gcconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class GCConfigStringHolder
INT_CONFIG (GCHeapHardLimitLOHPercent, "GCHeapHardLimitLOHPercent", "System.GC.HeapHardLimitLOHPercent", 0, "Specifies the GC heap LOH usage as a percentage of the total memory") \
INT_CONFIG (GCHeapHardLimitPOHPercent, "GCHeapHardLimitPOHPercent", "System.GC.HeapHardLimitPOHPercent", 0, "Specifies the GC heap POH usage as a percentage of the total memory") \
INT_CONFIG (GCEnabledInstructionSets, "GCEnabledInstructionSets", NULL, -1, "Specifies whether GC can use AVX2 or AVX512F - 0 for neither, 1 for AVX2, 3 for AVX512F")\
INT_CONFIG (GCConserveMem, "GCConserveMemory", NULL, 0, "Specifies how hard GC should try to conserve memory - values 0-9") \

// This class is responsible for retreiving configuration information
// for how the GC should operate.
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/gc/gcpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -3187,6 +3187,8 @@ class gc_heap
PER_HEAP_ISOLATED
size_t get_total_gen_estimated_reclaim (int gen_number);
PER_HEAP_ISOLATED
size_t get_total_gen_size (int gen_number);
PER_HEAP_ISOLATED
void get_memory_info (uint32_t* memory_load,
uint64_t* available_physical=NULL,
uint64_t* available_page_file=NULL);
Expand Down Expand Up @@ -4663,6 +4665,9 @@ class gc_heap
PER_HEAP_ISOLATED
int generation_skip_ratio_threshold;

PER_HEAP_ISOLATED
int conserve_mem_setting;

PER_HEAP
BOOL gen0_bricks_cleared;
PER_HEAP
Expand Down

0 comments on commit bd7b8e5

Please sign in to comment.