@@ -37863,15 +37863,26 @@ size_t GCHeap::ApproxTotalBytesInUse(BOOL small_heap_only)
3786337863 size_t totsize = 0;
3786437864 enter_spin_lock (&pGenGCHeap->gc_lock);
3786537865
37866- heap_segment* eph_seg = generation_allocation_segment (pGenGCHeap->generation_of (0));
37867- // Get small block heap size info
37868- totsize = (pGenGCHeap->alloc_allocated - heap_segment_mem (eph_seg));
37869- heap_segment* seg1 = generation_start_segment (pGenGCHeap->generation_of (max_generation));
37870- while (seg1 != eph_seg)
37871- {
37872- totsize += heap_segment_allocated (seg1) -
37873- heap_segment_mem (seg1);
37874- seg1 = heap_segment_next (seg1);
37866+ // the complication with the following code is that background GC may
37867+ // remove the ephemeral segment while we are iterating
37868+ // if so, we retry a couple times and ultimately may report a slightly wrong result
37869+ for (int tries = 1; tries <= 3; tries++)
37870+ {
37871+ heap_segment* eph_seg = generation_allocation_segment (pGenGCHeap->generation_of (0));
37872+ // Get small block heap size info
37873+ totsize = (pGenGCHeap->alloc_allocated - heap_segment_mem (eph_seg));
37874+ heap_segment* seg1 = generation_start_segment (pGenGCHeap->generation_of (max_generation));
37875+ while ((seg1 != eph_seg) && (seg1 != nullptr) && (seg1 != pGenGCHeap->freeable_soh_segment))
37876+ {
37877+ if (!heap_segment_decommitted_p (seg1))
37878+ {
37879+ totsize += heap_segment_allocated (seg1) -
37880+ heap_segment_mem (seg1);
37881+ }
37882+ seg1 = heap_segment_next (seg1);
37883+ }
37884+ if (seg1 == eph_seg)
37885+ break;
3787537886 }
3787637887
3787737888 //discount the fragmentation
0 commit comments