@@ -68,8 +68,8 @@ public void underThreshold_noOom() throws Exception {
68
68
options .oomMoreEagerlyThreshold = 99 ;
69
69
underTest .setOptions (options );
70
70
71
- underTest .handle (percentUsedAfterOtherGc (100 ));
72
- underTest .handle (percentUsedAfterForcedGc (89 ));
71
+ underTest .handle (percentUsedAfterOrganicFullGc (100 ));
72
+ underTest .handle (percentUsedAfterManualGc (89 ));
73
73
74
74
verifyNoInteractions (bugReporter );
75
75
assertStats (MemoryPressureStats .newBuilder ().setManuallyTriggeredGcs (1 ));
@@ -81,9 +81,9 @@ public void overThreshold_oom() throws Exception {
81
81
underTest .setOptions (options );
82
82
83
83
// Triggers GC, and tells RetainedHeapLimiter to OOM if too much memory used next time.
84
- underTest .handle (percentUsedAfterOtherGc (91 ));
84
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
85
85
86
- underTest .handle (percentUsedAfterForcedGc (91 ));
86
+ underTest .handle (percentUsedAfterManualGc (91 ));
87
87
88
88
ArgumentCaptor <Crash > crashArgument = ArgumentCaptor .forClass (Crash .class );
89
89
verify (bugReporter ).handleCrash (crashArgument .capture (), ArgumentMatchers .any ());
@@ -100,15 +100,15 @@ public void inactiveAfterOom() throws Exception {
100
100
options .minTimeBetweenTriggeredGc = Duration .ZERO ;
101
101
underTest .setOptions (options );
102
102
103
- underTest .handle (percentUsedAfterOtherGc (91 ));
104
- underTest .handle (percentUsedAfterForcedGc (91 ));
103
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
104
+ underTest .handle (percentUsedAfterManualGc (91 ));
105
105
verify (bugReporter ).handleCrash (any (), any ());
106
106
107
107
// No more GC or bug reports even if notifications come in after an OOM is in progress.
108
108
WeakReference <?> ref = new WeakReference <>(new Object ());
109
109
clock .advanceMillis (Duration .ofMinutes (1 ).toMillis ());
110
- underTest .handle (percentUsedAfterOtherGc (91 ));
111
- underTest .handle (percentUsedAfterForcedGc (91 ));
110
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
111
+ underTest .handle (percentUsedAfterManualGc (91 ));
112
112
assertThat (ref .get ()).isNotNull ();
113
113
verifyNoMoreBugReports ();
114
114
@@ -121,10 +121,10 @@ public void externalGcNoTrigger() throws Exception {
121
121
underTest .setOptions (options );
122
122
123
123
// No trigger because cause was "System.gc()".
124
- underTest .handle (percentUsedAfterForcedGc (91 ));
124
+ underTest .handle (percentUsedAfterManualGc (91 ));
125
125
126
126
// Proof: no OOM.
127
- underTest .handle (percentUsedAfterForcedGc (91 ));
127
+ underTest .handle (percentUsedAfterManualGc (91 ));
128
128
verifyNoInteractions (bugReporter );
129
129
130
130
assertStats (MemoryPressureStats .newBuilder ().setManuallyTriggeredGcs (0 ));
@@ -135,13 +135,13 @@ public void triggerReset() throws Exception {
135
135
options .oomMoreEagerlyThreshold = 90 ;
136
136
underTest .setOptions (options );
137
137
138
- underTest .handle (percentUsedAfterOtherGc (91 ));
138
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
139
139
140
140
// Got under the threshold, so no OOM.
141
- underTest .handle (percentUsedAfterForcedGc (89 ));
141
+ underTest .handle (percentUsedAfterManualGc (89 ));
142
142
143
143
// No OOM this time since wasn't triggered.
144
- underTest .handle (percentUsedAfterForcedGc (91 ));
144
+ underTest .handle (percentUsedAfterManualGc (91 ));
145
145
verifyNoInteractions (bugReporter );
146
146
}
147
147
@@ -150,9 +150,9 @@ public void triggerRaceWithOtherGc() throws Exception {
150
150
options .oomMoreEagerlyThreshold = 90 ;
151
151
underTest .setOptions (options );
152
152
153
- underTest .handle (percentUsedAfterOtherGc (91 ));
154
- underTest .handle (percentUsedAfterOtherGc (91 ));
155
- underTest .handle (percentUsedAfterForcedGc (91 ));
153
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
154
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
155
+ underTest .handle (percentUsedAfterManualGc (91 ));
156
156
157
157
ArgumentCaptor <Crash > crashArgument = ArgumentCaptor .forClass (Crash .class );
158
158
verify (bugReporter ).handleCrash (crashArgument .capture (), ArgumentMatchers .any ());
@@ -166,13 +166,13 @@ public void minTimeBetweenGc_lessThan_noGc() throws Exception {
166
166
underTest .setOptions (options );
167
167
WeakReference <?> ref = new WeakReference <>(new Object ());
168
168
169
- underTest .handle (percentUsedAfterOtherGc (91 ));
169
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
170
170
assertThat (ref .get ()).isNull ();
171
- underTest .handle (percentUsedAfterForcedGc (89 ));
171
+ underTest .handle (percentUsedAfterManualGc (89 ));
172
172
173
173
ref = new WeakReference <>(new Object ());
174
174
clock .advanceMillis (Duration .ofSeconds (59 ).toMillis ());
175
- underTest .handle (percentUsedAfterOtherGc (91 ));
175
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
176
176
assertThat (ref .get ()).isNotNull ();
177
177
178
178
assertStats (
@@ -188,13 +188,13 @@ public void minTimeBetweenGc_greaterThan_gc() throws Exception {
188
188
underTest .setOptions (options );
189
189
WeakReference <?> ref = new WeakReference <>(new Object ());
190
190
191
- underTest .handle (percentUsedAfterOtherGc (91 ));
191
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
192
192
assertThat (ref .get ()).isNull ();
193
- underTest .handle (percentUsedAfterForcedGc (89 ));
193
+ underTest .handle (percentUsedAfterManualGc (89 ));
194
194
195
195
ref = new WeakReference <>(new Object ());
196
196
clock .advanceMillis (Duration .ofSeconds (61 ).toMillis ());
197
- underTest .handle (percentUsedAfterOtherGc (91 ));
197
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
198
198
assertThat (ref .get ()).isNull ();
199
199
200
200
assertStats (
@@ -203,34 +203,63 @@ public void minTimeBetweenGc_greaterThan_gc() throws Exception {
203
203
.setMaxConsecutiveIgnoredGcsOverThreshold (0 ));
204
204
}
205
205
206
+ @ Test
207
+ public void gcLockerDefersManualGc_timeoutCancelled () throws Exception {
208
+ options .oomMoreEagerlyThreshold = 90 ;
209
+ options .minTimeBetweenTriggeredGc = Duration .ofMinutes (1 );
210
+ underTest .setOptions (options );
211
+
212
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
213
+ WeakReference <?> ref = new WeakReference <>(new Object ());
214
+ underTest .handle (percentUsedAfterGcLockerGc (91 ));
215
+ assertThat (ref .get ()).isNull ();
216
+
217
+ assertStats (MemoryPressureStats .newBuilder ().setManuallyTriggeredGcs (2 ));
218
+ }
219
+
220
+ @ Test
221
+ public void gcLockerAfterSuccessfulManualGc_timeoutPreserved () throws Exception {
222
+ options .oomMoreEagerlyThreshold = 90 ;
223
+ options .minTimeBetweenTriggeredGc = Duration .ofMinutes (1 );
224
+ underTest .setOptions (options );
225
+
226
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
227
+ underTest .handle (percentUsedAfterManualGc (89 ));
228
+ WeakReference <?> ref = new WeakReference <>(new Object ());
229
+ underTest .handle (percentUsedAfterGcLockerGc (91 ));
230
+ assertThat (ref .get ()).isNotNull ();
231
+
232
+ assertStats (MemoryPressureStats .newBuilder ().setManuallyTriggeredGcs (1 ));
233
+ }
234
+
206
235
@ Test
207
236
public void reportsMaxConsecutiveIgnored () throws Exception {
208
237
options .oomMoreEagerlyThreshold = 90 ;
209
238
options .minTimeBetweenTriggeredGc = Duration .ofMinutes (1 );
210
239
underTest .setOptions (options );
211
240
212
- underTest .handle (percentUsedAfterOtherGc (91 ));
213
- underTest .handle (percentUsedAfterForcedGc (89 ));
241
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
242
+ underTest .handle (percentUsedAfterManualGc (89 ));
214
243
for (int i = 0 ; i < 6 ; i ++) {
215
- underTest .handle (percentUsedAfterOtherGc (91 ));
244
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
216
245
}
217
246
218
247
clock .advanceMillis (Duration .ofMinutes (2 ).toMillis ());
219
248
220
- underTest .handle (percentUsedAfterOtherGc (91 ));
221
- underTest .handle (percentUsedAfterForcedGc (89 ));
249
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
250
+ underTest .handle (percentUsedAfterManualGc (89 ));
222
251
for (int i = 0 ; i < 8 ; i ++) {
223
- underTest .handle (percentUsedAfterOtherGc (91 ));
252
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
224
253
}
225
- underTest .handle (percentUsedAfterOtherGc (89 )); // Breaks the streak of over threshold events .
226
- underTest .handle (percentUsedAfterOtherGc (91 ));
254
+ underTest .handle (percentUsedAfterOrganicFullGc (89 )); // Breaks the streak of over threshold GCs .
255
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
227
256
228
257
clock .advanceMillis (Duration .ofMinutes (2 ).toMillis ());
229
258
230
- underTest .handle (percentUsedAfterOtherGc (91 ));
231
- underTest .handle (percentUsedAfterOtherGc (89 ));
259
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
260
+ underTest .handle (percentUsedAfterOrganicFullGc (89 ));
232
261
for (int i = 0 ; i < 7 ; i ++) {
233
- underTest .handle (percentUsedAfterOtherGc (91 ));
262
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
234
263
}
235
264
236
265
assertStats (
@@ -245,15 +274,15 @@ public void threshold100_noGcTriggeredEvenWithNonsenseStats() throws Exception {
245
274
underTest .setOptions (options );
246
275
WeakReference <?> ref = new WeakReference <>(new Object ());
247
276
248
- underTest .handle (percentUsedAfterOtherGc (101 ));
277
+ underTest .handle (percentUsedAfterOrganicFullGc (101 ));
249
278
assertThat (ref .get ()).isNotNull ();
250
279
251
280
assertStats (MemoryPressureStats .newBuilder ().setManuallyTriggeredGcs (0 ));
252
281
}
253
282
254
283
@ Test
255
284
public void worksWithoutSettingOptions () {
256
- underTest .handle (percentUsedAfterOtherGc (95 ));
285
+ underTest .handle (percentUsedAfterOrganicFullGc (95 ));
257
286
assertStats (MemoryPressureStats .newBuilder ().setManuallyTriggeredGcs (0 ));
258
287
}
259
288
@@ -262,7 +291,7 @@ public void statsReset() throws Exception {
262
291
options .oomMoreEagerlyThreshold = 90 ;
263
292
underTest .setOptions (options );
264
293
265
- underTest .handle (percentUsedAfterOtherGc (91 ));
294
+ underTest .handle (percentUsedAfterOrganicFullGc (91 ));
266
295
267
296
assertStats (MemoryPressureStats .newBuilder ().setManuallyTriggeredGcs (1 ));
268
297
assertStats (MemoryPressureStats .newBuilder ().setManuallyTriggeredGcs (0 ));
@@ -277,22 +306,23 @@ public void invalidThreshold_throws(@TestParameter({"-1", "101"}) int threshold)
277
306
.isEqualTo (Code .EXPERIMENTAL_OOM_MORE_EAGERLY_THRESHOLD_INVALID_VALUE );
278
307
}
279
308
280
- private static MemoryPressureEvent percentUsedAfterForcedGc (int percentUsed ) {
281
- return percentUsedAfterGc (/* wasManualGc= */ true , percentUsed );
309
+ private static MemoryPressureEvent percentUsedAfterManualGc (int percentUsed ) {
310
+ return percentUsedAfterGc (percentUsed ).setWasManualGc (true ).setWasFullGc (true ).build ();
311
+ }
312
+
313
+ private static MemoryPressureEvent percentUsedAfterOrganicFullGc (int percentUsed ) {
314
+ return percentUsedAfterGc (percentUsed ).setWasFullGc (true ).build ();
282
315
}
283
316
284
- private static MemoryPressureEvent percentUsedAfterOtherGc (int percentUsed ) {
285
- return percentUsedAfterGc (/* wasManualGc= */ false , percentUsed );
317
+ private static MemoryPressureEvent percentUsedAfterGcLockerGc (int percentUsed ) {
318
+ return percentUsedAfterGc (percentUsed ). setWasGcLockerInitiatedGc ( true ). build ( );
286
319
}
287
320
288
- private static MemoryPressureEvent percentUsedAfterGc (boolean wasManualGc , int percentUsed ) {
321
+ private static MemoryPressureEvent . Builder percentUsedAfterGc (int percentUsed ) {
289
322
checkArgument (percentUsed >= 0 , percentUsed );
290
323
return MemoryPressureEvent .newBuilder ()
291
- .setWasManualGc (wasManualGc )
292
- .setWasFullGc (true )
293
324
.setTenuredSpaceUsedBytes (percentUsed )
294
- .setTenuredSpaceMaxBytes (100L )
295
- .build ();
325
+ .setTenuredSpaceMaxBytes (100L );
296
326
}
297
327
298
328
private void assertStats (MemoryPressureStats .Builder expected ) {
0 commit comments