Skip to content

Commit fedfeca

Browse files
committed
fixes for decommitting large+huge and comments
1 parent d3cfeb8 commit fedfeca

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

src/coreclr/gc/gc.cpp

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13373,21 +13373,25 @@ void gc_heap::age_free_regions (const char* msg)
1337313373
// though perhaps BGC can leave them there. Future work could verify and assert this.)
1337413374
// b. Move any basic region in global_regions_to_decommit (which means we intended to decommit them
1337513375
// but haven't done so yet) to surplus_regions
13376-
// b. Move all huge regions that are past the age threshold from global_free_huge_regions to aged_regions
13377-
// c. Move all basic/large regions that are past the age threshold from free_regions to aged_regions
13376+
// c. Move all huge regions that are past the age threshold from global_free_huge_regions to aged_regions
13377+
// d. Move all basic/large regions that are past the age threshold from free_regions to aged_regions
1337813378
// 2. Move all regions from aged_regions to global_regions_to_decommit. Note that the intention is to
1337913379
// combine this with move_highest_free_regions in a future change, which is why we don't just do this
13380-
// in steps 1b/1c.
13380+
// in steps 1c/1d.
1338113381
// 3. Compute the required per-heap budgets for SOH (basic regions) and the balance. The budget for LOH
13382-
// (large/huge) is zero as we are using an entirely age-based approach.
13382+
// (large) is zero as we are using an entirely age-based approach.
1338313383
// balance = (number of free regions) - budget
1338413384
// 4. Decide if we are going to distribute or decommit a nonzero balance. To distribute, we adjust the
13385-
// per-heap budgets, so after this step the LOH (large/huge) budgets can be positive.
13386-
// a. A negative balance (deficit) must be distributed since decommitting a negative number of regions
13387-
// doesn't make sense. A negative balance isn't possible for LOH since the budgets start at zero.
13385+
// per-heap budgets, so after this step the LOH (large) budgets can be positive.
13386+
// a. A negative balance (deficit) for SOH (basic) will be distributed it means we expect to use
13387+
// more memory than we have on the free lists. A negative balance for LOH (large) isn't possible
13388+
// for LOH since the budgets start at zero.
1338813389
// b. For SOH (basic), we will decommit surplus regions unless we are in a foreground GC during BGC.
13389-
// c. For LOH (large/huge), we will distribute surplus regions since we are using an entirely age-based
13390-
// approach. However, if we are in a high-memory-usage scenario, we will decommit.
13390+
// c. For LOH (large), we will distribute surplus regions since we are using an entirely age-based
13391+
// approach. However, if we are in a high-memory-usage scenario, we will decommit. In this case,
13392+
// we will also decommit the huge regions in global_free_huge_regions. Note that they were not
13393+
// originally included in the balance because they are kept in a global list. Only basic/large
13394+
// regions are kept in per-heap lists where they can be distributed.
1339113395
// 5. Implement the distribute-or-decommit strategy. To distribute, we simply move regions across heaps,
1339213396
// using surplus_regions as a holding space. To decommit, for server GC we generally leave them on the
1339313397
// global_regions_to_decommit list and decommit them over time. However, in high-memory-usage scenarios,
@@ -13518,22 +13522,22 @@ void gc_heap::distribute_free_regions()
1351813522
// if so, put the highest free regions on the decommit list
1351913523
total_num_free_regions[kind] += surplus_regions[kind].get_num_free_regions();
1352013524

13521-
ptrdiff_t balance = total_num_free_regions[kind] - total_budget_in_region_units[kind];
13525+
ptrdiff_t balance_to_distribute = total_num_free_regions[kind] - total_budget_in_region_units[kind];
1352213526

13523-
if (distribute_surplus_p(balance, kind, aggressive_decommit_large_p))
13527+
if (distribute_surplus_p(balance_to_distribute, kind, aggressive_decommit_large_p))
1352413528
{
1352513529
#ifdef MULTIPLE_HEAPS
1352613530
// we may have a deficit or - for large regions or if background GC is going on - a surplus.
1352713531
// adjust the budget per heap accordingly
13528-
if (balance != 0)
13532+
if (balance_to_distribute != 0)
1352913533
{
13530-
dprintf (REGIONS_LOG, ("distributing the %zd %s regions deficit", -balance, free_region_kind_name[kind]));
13534+
dprintf (REGIONS_LOG, ("distributing the %zd %s regions deficit", -balance_to_distribute, free_region_kind_name[kind]));
1353113535

1353213536
ptrdiff_t curr_balance = 0;
1353313537
ptrdiff_t rem_balance = 0;
1353413538
for (int i = 0; i < n_heaps; i++)
1353513539
{
13536-
curr_balance += balance;
13540+
curr_balance += balance_to_distribute;
1353713541
ptrdiff_t adjustment_per_heap = curr_balance / n_heaps;
1353813542
curr_balance -= adjustment_per_heap * n_heaps;
1353913543
ptrdiff_t new_budget = (ptrdiff_t)heap_budget_in_region_units[kind][i] + adjustment_per_heap;
@@ -13577,20 +13581,28 @@ void gc_heap::distribute_free_regions()
1357713581
}
1357813582
else
1357913583
{
13580-
assert (balance >= 0);
13584+
assert (balance_to_distribute >= 0);
13585+
13586+
ptrdiff_t balance_to_decommit = balance_to_distribute;
13587+
if (kind == large_free_region)
13588+
{
13589+
// huge regions aren't part of balance_to_distribute because they are kept in a global list
13590+
// and therefore can't be distributed across heaps
13591+
balance_to_decommit += global_free_huge_regions.get_size_free_regions() / global_region_allocator.get_large_region_alignment();
13592+
}
1358113593

1358213594
dprintf(REGIONS_LOG, ("distributing the %zd %s regions, removing %zd regions",
1358313595
total_budget_in_region_units[kind],
1358413596
free_region_kind_name[kind],
1358513597
balance));
1358613598

13587-
if (balance > 0)
13599+
if (balance_to_decommit > 0)
1358813600
{
1358913601
// remember how many regions we had on the decommit list already due to aging
1359013602
size_t num_regions_to_decommit_before = global_regions_to_decommit[kind].get_num_free_regions();
1359113603

1359213604
// put the highest regions on the decommit list
13593-
global_region_allocator.move_highest_free_regions (balance * region_factor[kind],
13605+
global_region_allocator.move_highest_free_regions (balance_to_decommit * region_factor[kind],
1359413606
kind == basic_free_region,
1359513607
global_regions_to_decommit);
1359613608

@@ -13601,7 +13613,7 @@ void gc_heap::distribute_free_regions()
1360113613
{
1360213614
// we should now have 'balance' regions more on the decommit list
1360313615
assert (global_regions_to_decommit[kind].get_num_free_regions() ==
13604-
num_regions_to_decommit_before + (size_t)balance);
13616+
num_regions_to_decommit_before + (size_t)balance_to_decommit);
1360513617
}
1360613618
else
1360713619
{

0 commit comments

Comments
 (0)