155
155
This should help weak consistency archs.
156
156
*/
157
157
#include "config.h"
158
-
159
158
#ifdef HAVE_SGEN_GC
160
159
161
160
#ifdef __MACH__
@@ -4091,89 +4090,92 @@ guint64 memory_pressure_gc_count = 0;
4091
4090
guint64 memory_pressure_iteration = 0 ;
4092
4091
guint64 memory_pressure_adds [MEM_PRESSURE_COUNT ] = {0 , 0 , 0 , 0 };
4093
4092
guint64 memory_pressure_removes [MEM_PRESSURE_COUNT ] = {0 , 0 , 0 , 0 }; // history of memory pressure removals
4094
- const unsigned min_memorypressure_budget = 4 * 1024 * 1024 ; // 4 MB
4093
+ const unsigned min_memorypressure_budget = 4 * 1024 * 1024 ; // 4 MB
4095
4094
4096
4095
// Resets pressure accounting after a gen2 GC has occurred.
4097
4096
static void check_pressure_counts ()
4098
4097
{
4099
- if (memory_pressure_gc_count != sgen_gc_collection_count (GENERATION_OLD ))
4100
- {
4101
- memory_pressure_gc_count = sgen_gc_collection_count (GENERATION_OLD );
4102
- memory_pressure_iteration ++ ;
4098
+ if (memory_pressure_gc_count != sgen_gc_collection_count (GENERATION_OLD )) {
4099
+ memory_pressure_gc_count = sgen_gc_collection_count (GENERATION_OLD );
4100
+ memory_pressure_iteration ++ ;
4103
4101
4104
- guint32 p = memory_pressure_iteration % MEM_PRESSURE_COUNT ;
4102
+ guint32 p = memory_pressure_iteration % MEM_PRESSURE_COUNT ;
4105
4103
4106
- memory_pressure_adds [p ] = 0 ; // new pressure will be accumulated here
4107
- memory_pressure_removes [p ] = 0 ;
4108
- }
4104
+ memory_pressure_adds [p ] = 0 ; // new pressure will be accumulated here
4105
+ memory_pressure_removes [p ] = 0 ;
4106
+ }
4109
4107
}
4110
4108
4111
4109
void sgen_remove_memory_pressure (guint64 bytes_allocated )
4112
4110
{
4113
- check_pressure_counts ();
4111
+ check_pressure_counts ();
4114
4112
4115
- guint32 p = memory_pressure_iteration % MEM_PRESSURE_COUNT ;
4113
+ guint32 p = memory_pressure_iteration % MEM_PRESSURE_COUNT ;
4116
4114
4117
- mono_atomic_fetch_add_i64 ((gint64 * )& memory_pressure_removes [p ], bytes_allocated );
4115
+ mono_atomic_fetch_add_i64 ((gint64 * )& memory_pressure_removes [p ], bytes_allocated );
4118
4116
}
4119
4117
4120
- void sgen_add_memory_pressure (guint64 bytes_allocated )
4118
+
4119
+ static gboolean pressure_check_heuristic (guint64 new_mem_value )
4121
4120
{
4122
4121
4123
- check_pressure_counts ();
4124
-
4125
- guint p = memory_pressure_iteration % MEM_PRESSURE_COUNT ;
4126
-
4127
- guint64 new_mem_value = mono_atomic_fetch_add_i64 ((gint64 * )& memory_pressure_adds [p ], bytes_allocated );
4128
-
4129
- // AddMemoryPressure contains unrolled loops which depend on MEM_PRESSURE_COUNT
4130
- g_assert (MEM_PRESSURE_COUNT == 4 );
4131
-
4132
- guint64 add = memory_pressure_adds [0 ] + memory_pressure_adds [1 ] + memory_pressure_adds [2 ] + memory_pressure_adds [3 ] - memory_pressure_adds [p ];
4133
- guint64 rem = memory_pressure_removes [0 ] + memory_pressure_removes [1 ] + memory_pressure_removes [2 ] + memory_pressure_removes [3 ] - memory_pressure_removes [p ];
4134
-
4135
- if (new_mem_value >= min_memorypressure_budget )
4136
- {
4137
- guint64 budget = min_memorypressure_budget ;
4138
-
4139
- if (memory_pressure_iteration >= MEM_PRESSURE_COUNT ) // wait until we have enough data points
4140
- {
4141
- // Adjust according to effectiveness of GC
4142
- // Scale budget according to past memory_pressure_adds / memory_pressure_removes ratio
4143
- if (add >= rem * MAX_MEMORYPRESSURE_RATIO )
4144
- {
4145
- budget = min_memorypressure_budget * MAX_MEMORYPRESSURE_RATIO ;
4146
- }
4147
- else if (add > rem )
4148
- {
4149
- g_assert (rem != 0 );
4150
-
4151
- // Avoid overflow by calculating addPressure / remPressure as fixed point (1 = 1024)
4152
- budget = (add * 1024 / rem ) * budget / 1024 ;
4153
- }
4154
- }
4155
-
4156
- // If still over budget, check current managed heap size
4157
- if (new_mem_value >= budget )
4158
- {
4159
- guint64 heap_over_3 = sgen_gc_info .heap_size_bytes / 3 ;
4160
-
4161
- if (budget < heap_over_3 ) // Max
4162
- {
4163
- budget = heap_over_3 ;
4164
- }
4165
-
4166
- if (new_mem_value >= budget )
4167
- {
4168
- // last check - if we would exceed 20% of GC "duty cycle", do not trigger GC at this time
4169
- if ((size_t )(mono_time_since_last_stw () + time_last ) > (time_last * 5 ))
4170
- {
4171
- sgen_gc_collect (GENERATION_OLD );
4172
- check_pressure_counts ();
4122
+ guint64 add = 0 ;
4123
+ guint64 rem = 0 ;
4124
+
4125
+ for (gint i = 0 ; i < MEM_PRESSURE_COUNT ; i ++ ) {
4126
+ add += memory_pressure_adds [i ];
4127
+ rem += memory_pressure_removes [i ];
4128
+ }
4129
+
4130
+ if (new_mem_value >= min_memorypressure_budget ) {
4131
+ guint64 budget = min_memorypressure_budget ;
4132
+
4133
+ if (memory_pressure_iteration >= MEM_PRESSURE_COUNT ) { // wait until we have enough data points
4134
+ // Adjust according to effectiveness of GC
4135
+ // Scale budget according to past memory_pressure_adds / memory_pressure_removes ratio
4136
+ if (add >= rem * MAX_MEMORYPRESSURE_RATIO )
4137
+ {
4138
+ budget = min_memorypressure_budget * MAX_MEMORYPRESSURE_RATIO ;
4139
+ }
4140
+ else if (add > rem )
4141
+ {
4142
+ g_assert (rem != 0 );
4143
+ // Avoid overflow by calculating addPressure / remPressure as fixed point (1 = 1024)
4144
+ budget = (add * 1024 / rem ) * budget / 1024 ;
4145
+ }
4146
+ }
4147
+
4148
+ // If still over budget, check current managed heap size
4149
+ if (new_mem_value >= budget ) {
4150
+ guint64 heap_over_3 = sgen_gc_info .heap_size_bytes / 3 ;
4151
+
4152
+ if (budget < heap_over_3 ) {
4153
+ budget = heap_over_3 ;
4154
+ }
4155
+ if (new_mem_value >= budget ) {
4156
+ // last check - if we would exceed 20% of GC "duty cycle", do not trigger GC at this time
4157
+ if ((size_t )(mono_time_since_last_stw () + time_last ) > (time_last * 5 )) {
4158
+ return TRUE;
4159
+ }
4160
+ }
4173
4161
}
4174
- }
4175
- }
4176
- }
4162
+ }
4163
+
4164
+ return FALSE;
4177
4165
}
4178
4166
4179
- #endif /* HAVE_SGEN_GC */
4167
+ void sgen_add_memory_pressure (guint64 bytes_allocated )
4168
+ {
4169
+
4170
+ check_pressure_counts ();
4171
+
4172
+ guint p = memory_pressure_iteration % MEM_PRESSURE_COUNT ;
4173
+
4174
+ guint64 new_mem_value = mono_atomic_fetch_add_i64 ((gint64 * )& memory_pressure_adds [p ], bytes_allocated );
4175
+
4176
+ if (pressure_check_heuristic (new_mem_value )) {
4177
+ sgen_gc_collect (GENERATION_OLD );
4178
+ check_pressure_counts ();
4179
+ }
4180
+ }
4181
+ #endif /* HAVE_SGEN_GC */
0 commit comments