@@ -21,12 +21,14 @@ internal class ClrOptimizationMiddleware
21
21
private readonly ILogger _logger ;
22
22
private readonly RequestDelegate _next ;
23
23
private readonly IScriptWebHostEnvironment _webHostEnvironment ;
24
+ private readonly IEnvironment _environment ;
24
25
private RequestDelegate _invoke ;
25
26
private double _specialized = 0 ;
26
27
27
- public ClrOptimizationMiddleware ( RequestDelegate next , IScriptWebHostEnvironment webHostEnvironment , ILogger < SystemTraceMiddleware > logger )
28
+ public ClrOptimizationMiddleware ( RequestDelegate next , IScriptWebHostEnvironment webHostEnvironment , IEnvironment environment , ILogger < ClrOptimizationMiddleware > logger )
28
29
{
29
30
_webHostEnvironment = webHostEnvironment ;
31
+ _environment = environment ;
30
32
_logger = logger ;
31
33
_next = next ;
32
34
_invoke = InvokeClrOptimizationCheck ;
@@ -53,28 +55,31 @@ private void StartStopGCAsBestEffort()
53
55
{
54
56
try
55
57
{
56
- if ( _webHostEnvironment . InStandbyMode )
58
+ // optimization not intended for single core VMs
59
+ if ( _webHostEnvironment . InStandbyMode && _environment . GetEffectiveCoresCount ( ) > 1 )
57
60
{
58
- // This is just to make sure we do not enter NoGCRegion multiple times during standby mode.
59
- if ( GCSettings . LatencyMode != GCLatencyMode . NoGCRegion )
61
+ // If in placeholder mode and already in NoGCRegion, let's end it then start NoGCRegion again.
62
+ // This may happen if there are multiple warmup calls(few minutes apart) during placeholder mode and before specialization.
63
+ if ( GCSettings . LatencyMode == GCLatencyMode . NoGCRegion )
64
+ {
65
+ GC . EndNoGCRegion ( ) ;
66
+ }
67
+
68
+ // In standby mode, we enter NoGCRegion mode as best effort.
69
+ // This is to try to avoid GC during cold start specialization.
70
+ if ( ! GC . TryStartNoGCRegion ( AllocationBudgetForGCDuringSpecialization , disallowFullBlockingGC : false ) )
60
71
{
61
- // In standby mode, we enforce a GC then enter NoGCRegion mode as best effort.
62
- // This is to try to avoid GC during cold start specialization.
63
- GC . Collect ( ) ;
64
- if ( ! GC . TryStartNoGCRegion ( AllocationBudgetForGCDuringSpecialization , disallowFullBlockingGC : false ) )
65
- {
66
- _logger . LogError ( $ "CLR runtime failed to commit the requested amount of memory: { AllocationBudgetForGCDuringSpecialization } ") ;
67
- }
68
- _logger . LogInformation ( $ "Collection count for gen 0: { GC . CollectionCount ( 0 ) } , gen 1: { GC . CollectionCount ( 1 ) } , gen 2: { GC . CollectionCount ( 2 ) } ") ;
72
+ _logger . LogError ( $ "CLR runtime GC failed to commit the requested amount of memory: { AllocationBudgetForGCDuringSpecialization } ") ;
69
73
}
74
+ _logger . LogInformation ( $ "GC Collection count for gen 0: { GC . CollectionCount ( 0 ) } , gen 1: { GC . CollectionCount ( 1 ) } , gen 2: { GC . CollectionCount ( 2 ) } ") ;
70
75
}
71
76
else
72
77
{
73
78
// if not in standby mode and we are in NoGCRegion then we end NoGCRegion.
74
79
if ( GCSettings . LatencyMode == GCLatencyMode . NoGCRegion )
75
80
{
76
81
GC . EndNoGCRegion ( ) ;
77
- _logger . LogInformation ( $ "Collection count for gen 0: { GC . CollectionCount ( 0 ) } , gen 1: { GC . CollectionCount ( 1 ) } , gen 2: { GC . CollectionCount ( 2 ) } ") ;
82
+ _logger . LogInformation ( $ "GC Collection count for gen 0: { GC . CollectionCount ( 0 ) } , gen 1: { GC . CollectionCount ( 1 ) } , gen 2: { GC . CollectionCount ( 2 ) } ") ;
78
83
}
79
84
80
85
// This logic needs to run only once during specialization, so replacing the RequestDelegate after specialization
@@ -86,7 +91,8 @@ private void StartStopGCAsBestEffort()
86
91
}
87
92
catch ( Exception ex )
88
93
{
89
- _logger . LogError ( ex . Message ) ;
94
+ // Just logging it at informational.
95
+ _logger . LogInformation ( ex , "GC optimization will not get applied." ) ;
90
96
}
91
97
}
92
98
}
0 commit comments