1
1
/*
2
- * Copyright (c) 2014, 2023 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2014, 2024 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
31
31
import java .lang .reflect .*;
32
32
import java .lang .management .*;
33
33
import java .util .*;
34
+ import java .util .stream .Collectors ;
35
+
34
36
import javax .management .*;
35
37
import javax .management .openmbean .*;
36
38
import jdk .test .lib .process .ProcessTools ;
@@ -85,6 +87,32 @@ private static Object getValue(String string) {
85
87
}
86
88
}
87
89
90
+ /**
91
+ * Get system load.
92
+ *
93
+ * <dl>
94
+ * <dt>load() ~= 1 </dt><dd> fully loaded system, all cores are used 100%</dd>
95
+ * <dt>load() < 1 </dt><dd> some cpu resources are available</dd>
96
+ * <dt>load() > 1 </dt><dd> system is overloaded</dd>
97
+ * </dl>
98
+ *
99
+ * @return the load of the system or Optional.empty() if the load can not be determined.
100
+ */
101
+ private static Optional <Double > systemLoad () {
102
+ OperatingSystemMXBean bean = ManagementFactory .getPlatformMXBean (OperatingSystemMXBean .class );
103
+ double average = bean .getSystemLoadAverage () / bean .getAvailableProcessors ();
104
+ return (average < 0 )
105
+ ? Optional .empty ()
106
+ : Optional .of (average );
107
+ }
108
+
109
+ private static String minMax (List <Optional <Double >> l ) {
110
+ DoubleSummaryStatistics minmax = l .stream ().flatMap (Optional ::stream ).collect (Collectors .summarizingDouble (d -> d ));
111
+ return minmax .getCount () != 0
112
+ ? "min: " + minmax .getMin () + ", max: " + minmax .getMax ()
113
+ : "could not gather load statistics from system" ;
114
+ }
115
+
88
116
private static void doFullGc (int numberOfTimes ) {
89
117
List <List <String >> newStrings = new ArrayList <List <String >>();
90
118
for (int i = 0 ; i < numberOfTimes ; i ++) {
@@ -179,13 +207,15 @@ private static void forceDeduplication(int ageThreshold, String gcType) {
179
207
}
180
208
}
181
209
182
- private static boolean waitForDeduplication (String s1 , String s2 ) {
210
+ private static void waitForDeduplication (String s1 , String s2 ) {
183
211
boolean first = true ;
184
212
int timeout = 10000 ; // 10sec in ms
185
213
int iterationWait = 100 ; // 100ms
214
+ List <Optional <Double >> loadHistory = new ArrayList <>();
186
215
for (int attempts = 0 ; attempts < (timeout / iterationWait ); attempts ++) {
216
+ loadHistory .add (systemLoad ());
187
217
if (getValue (s1 ) == getValue (s2 )) {
188
- return true ;
218
+ return ;
189
219
}
190
220
if (first ) {
191
221
System .out .println ("Waiting for deduplication..." );
@@ -194,10 +224,10 @@ private static boolean waitForDeduplication(String s1, String s2) {
194
224
try {
195
225
Thread .sleep (iterationWait );
196
226
} catch (Exception e ) {
197
- throw new RuntimeException (e );
227
+ throw new RuntimeException ("Deduplication has not occurred: Thread.sleep() threw" , e );
198
228
}
199
229
}
200
- return false ;
230
+ throw new RuntimeException ( "Deduplication has not occurred, load history: " + minMax ( loadHistory )) ;
201
231
}
202
232
203
233
private static String generateString (int id ) {
@@ -240,7 +270,9 @@ private static ArrayList<String> createStrings(int total, int unique) {
240
270
*/
241
271
private static void verifyStrings (ArrayList <String > list , int uniqueExpected ) {
242
272
boolean passed = false ;
273
+ List <Optional <Double >> loadHistory = new ArrayList <>();
243
274
for (int attempts = 0 ; attempts < 10 ; attempts ++) {
275
+ loadHistory .add (systemLoad ());
244
276
// Check number of deduplicated strings
245
277
ArrayList <Object > unique = new ArrayList <Object >(uniqueExpected );
246
278
for (String string : list ) {
@@ -277,7 +309,7 @@ private static void verifyStrings(ArrayList<String> list, int uniqueExpected) {
277
309
}
278
310
}
279
311
if (!passed ) {
280
- throw new RuntimeException ("String verification failed" );
312
+ throw new RuntimeException ("String verification failed, load history: " + minMax ( loadHistory ) );
281
313
}
282
314
}
283
315
@@ -361,9 +393,7 @@ public static void main(String[] args) {
361
393
// and be inserted into the deduplication hashtable.
362
394
forceDeduplication (ageThreshold , FullGC );
363
395
364
- if (!waitForDeduplication (dupString1 , baseString )) {
365
- throw new RuntimeException ("Deduplication has not occurred" );
366
- }
396
+ waitForDeduplication (dupString1 , baseString );
367
397
368
398
// Create a new duplicate of baseString
369
399
StringBuilder sb2 = new StringBuilder (baseString );
@@ -398,9 +428,7 @@ public static void main(String[] args) {
398
428
399
429
forceDeduplication (ageThreshold , FullGC );
400
430
401
- if (!waitForDeduplication (dupString3 , internedString )) {
402
- throw new RuntimeException ("Deduplication has not occurred for string 3" );
403
- }
431
+ waitForDeduplication (dupString3 , internedString );
404
432
405
433
if (afterInternedValue != getValue (dupString2 )) {
406
434
throw new RuntimeException ("Interned string value changed" );
0 commit comments