@@ -1979,7 +1979,7 @@ public void EnsureBGCRevisitInfoAlloc()
19791979 /// Amount of memory allocated since last GC. Requires GCAllocationTicks enabled. The
19801980 /// data is split into small and large heaps
19811981 /// </summary>
1982- public double [ ] AllocedSinceLastGCBasedOnAllocTickMB = { 0.0 , 0.0 } ; // Set in HeapStats
1982+ public double [ ] AllocedSinceLastGCBasedOnAllocTickMB = { 0.0 , 0.0 , 0.0 } ; // Set in HeapStats
19831983 /// <summary>
19841984 /// Number of heaps. -1 is the default
19851985 /// </summary>
@@ -2156,6 +2156,11 @@ public double SurvivalPercent(Gens gen)
21562156 {
21572157 double retSurvRate = double . NaN ;
21582158
2159+ if ( ! ValidGenData ( PerHeapHistories , gen ) )
2160+ {
2161+ return retSurvRate ;
2162+ }
2163+
21592164 long SurvRate = 0 ;
21602165
21612166 if ( gen == Gens . GenLargeObj || gen == Gens . GenPinObj )
@@ -2170,16 +2175,13 @@ public double SurvivalPercent(Gens gen)
21702175 return retSurvRate ;
21712176 }
21722177
2173- if ( PerHeapHistories != null && PerHeapHistories . Count > 0 )
2178+ for ( int i = 0 ; i < PerHeapHistories . Count ; i ++ )
21742179 {
2175- for ( int i = 0 ; i < PerHeapHistories . Count ; i ++ )
2176- {
2177- SurvRate += PerHeapHistories [ i ] . GenData [ ( int ) gen ] . SurvRate ;
2178- }
2179-
2180- SurvRate /= PerHeapHistories . Count ;
2180+ SurvRate += PerHeapHistories [ i ] . GenData [ ( int ) gen ] . SurvRate ;
21812181 }
21822182
2183+ SurvRate /= PerHeapHistories . Count ;
2184+
21832185 retSurvRate = SurvRate ;
21842186
21852187 return retSurvRate ;
@@ -2219,14 +2221,16 @@ public double GenSizeAfterMB(Gens gen)
22192221 Debug . Assert ( false ) ;
22202222 return double . NaN ;
22212223 }
2224+
2225+
22222226 /// <summary>
22232227 /// Heap fragmentation by generation (mb)
22242228 /// </summary>
22252229 /// <param name="gen"></param>
22262230 /// <returns></returns>
22272231 public double GenFragmentationMB ( Gens gen )
22282232 {
2229- if ( PerHeapHistories == null )
2233+ if ( ! ValidGenData ( PerHeapHistories , gen ) )
22302234 {
22312235 return double . NaN ;
22322236 }
@@ -2255,7 +2259,7 @@ public double GenFragmentationPercent(Gens gen)
22552259 /// <returns></returns>
22562260 public double GenInMB ( Gens gen )
22572261 {
2258- if ( PerHeapHistories == null )
2262+ if ( ! ValidGenData ( PerHeapHistories , gen ) )
22592263 {
22602264 return double . NaN ;
22612265 }
@@ -2275,7 +2279,7 @@ public double GenInMB(Gens gen)
22752279 /// <returns></returns>
22762280 public double GenOutMB ( Gens gen )
22772281 {
2278- if ( PerHeapHistories == null )
2282+ if ( ! ValidGenData ( PerHeapHistories , gen ) )
22792283 {
22802284 return double . NaN ;
22812285 }
@@ -2334,7 +2338,7 @@ public double GenPromotedMB(Gens gen)
23342338 /// <returns></returns>
23352339 public double GenBudgetMB ( Gens gen )
23362340 {
2337- if ( PerHeapHistories == null )
2341+ if ( ! ValidGenData ( PerHeapHistories , gen ) )
23382342 {
23392343 return double . NaN ;
23402344 }
@@ -2354,7 +2358,7 @@ public double GenBudgetMB(Gens gen)
23542358 /// <returns></returns>
23552359 public double GenObjSizeAfterMB ( Gens gen )
23562360 {
2357- if ( PerHeapHistories == null )
2361+ if ( ! ValidGenData ( PerHeapHistories , gen ) )
23582362 {
23592363 return double . NaN ;
23602364 }
@@ -2414,6 +2418,9 @@ public GCCondemnedReasons[] PerHeapCondemnedReasons
24142418 }
24152419 }
24162420
2421+ internal static bool ValidGenData ( List < GCPerHeapHistory > perHeapHistories , Gens gen )
2422+ => ! ( perHeapHistories == null || perHeapHistories . Count == 0 || perHeapHistories [ 0 ] . GenData . Length <= ( int ) gen ) ;
2423+
24172424 public enum TimingType
24182425 {
24192426 /// <summary>
@@ -2939,7 +2946,7 @@ internal static double GetHeapSizeBeforeMB(List<TraceGC> GCs, TraceGC gc)
29392946 // Per generation stats.
29402947 internal static double GetGenSizeBeforeMB ( List < TraceGC > GCs , TraceGC gc , Gens gen )
29412948 {
2942- if ( gc . PerHeapHistories != null && gc . PerHeapHistories . Count > 0 )
2949+ if ( ValidGenData ( gc . PerHeapHistories , gen ) )
29432950 {
29442951 double ret = 0.0 ;
29452952 for ( int HeapIndex = 0 ; HeapIndex < gc . PerHeapHistories . Count ; HeapIndex ++ )
@@ -2953,7 +2960,7 @@ internal static double GetGenSizeBeforeMB(List<TraceGC> GCs, TraceGC gc, Gens ge
29532960 return ret ;
29542961 }
29552962
2956- // When we don't have perheap history we can only estimate for gen0 and gen3 .
2963+ // When we don't have perheap history we can only estimate for gen0, gen3 and gen4 .
29572964 double Gen0SizeBeforeMB = 0 ;
29582965 if ( gen == Gens . Gen0 )
29592966 {
@@ -3031,6 +3038,12 @@ private static double GetUserAllocatedPerHeap(List<TraceGC> GCs, TraceGC gc, int
30313038 {
30323039 Debug . Assert ( HeapIndex < gc . PerHeapHistories . Count ) ;
30333040
3041+ // If the gen data isn't available for the specific PerHeapHistory, we can't calculate.
3042+ if ( ! ValidGenData ( gc . PerHeapHistories , gen ) )
3043+ {
3044+ return 0 ;
3045+ }
3046+
30343047 long prevObjSize = 0 ;
30353048 if ( gc . Index > 0 )
30363049 {
@@ -3048,6 +3061,7 @@ private static double GetUserAllocatedPerHeap(List<TraceGC> GCs, TraceGC gc, int
30483061 }
30493062 }
30503063 }
3064+
30513065 GCPerHeapHistoryGenData currentGenData = gc . PerHeapHistories [ HeapIndex ] . GenData [ ( int ) gen ] ;
30523066 double Allocated ;
30533067
@@ -3087,7 +3101,7 @@ private static double EstimateAllocSurv0(List<TraceGC> GCs, TraceGC gc, int Heap
30873101 {
30883102 // If the prevous GC has that heap get its size.
30893103 var perHeapGenData = GCs [ gc . Index - 1 ] . PerHeapHistories ;
3090- if ( perHeapGenData ? . Count > 0 && HeapIndex < perHeapGenData . Count )
3104+ if ( ValidGenData ( perHeapGenData , gen ) )
30913105 {
30923106 return perHeapGenData [ HeapIndex ] . GenData [ ( int ) gen ] . Budget ;
30933107 }
0 commit comments