8283223: gc/stringdedup/TestStringDeduplicationFullGC.java#Parallel failed with "RuntimeException: String verification failed"
Reviewed-by: tschatzl, kbarrett
This commit is contained in:
parent
44549b605a
commit
9d441e3e56
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,6 +31,8 @@ import com.sun.management.GarbageCollectionNotificationInfo;
|
|||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.lang.management.*;
|
import java.lang.management.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.management.*;
|
import javax.management.*;
|
||||||
import javax.management.openmbean.*;
|
import javax.management.openmbean.*;
|
||||||
import jdk.test.lib.process.ProcessTools;
|
import jdk.test.lib.process.ProcessTools;
|
||||||
@ -85,6 +87,32 @@ class TestStringDeduplicationTools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get system load.
|
||||||
|
*
|
||||||
|
* <dl>
|
||||||
|
* <dt>load() ~= 1 </dt><dd> fully loaded system, all cores are used 100%</dd>
|
||||||
|
* <dt>load() < 1 </dt><dd> some cpu resources are available</dd>
|
||||||
|
* <dt>load() > 1 </dt><dd> system is overloaded</dd>
|
||||||
|
* </dl>
|
||||||
|
*
|
||||||
|
* @return the load of the system or Optional.empty() if the load can not be determined.
|
||||||
|
*/
|
||||||
|
private static Optional<Double> systemLoad() {
|
||||||
|
OperatingSystemMXBean bean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
|
||||||
|
double average = bean.getSystemLoadAverage() / bean.getAvailableProcessors();
|
||||||
|
return (average < 0)
|
||||||
|
? Optional.empty()
|
||||||
|
: Optional.of(average);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String minMax(List<Optional<Double>> l) {
|
||||||
|
DoubleSummaryStatistics minmax = l.stream().flatMap(Optional::stream).collect(Collectors.summarizingDouble(d -> d));
|
||||||
|
return minmax.getCount() != 0
|
||||||
|
? "min: " + minmax.getMin() + ", max: " + minmax.getMax()
|
||||||
|
: "could not gather load statistics from system";
|
||||||
|
}
|
||||||
|
|
||||||
private static void doFullGc(int numberOfTimes) {
|
private static void doFullGc(int numberOfTimes) {
|
||||||
List<List<String>> newStrings = new ArrayList<List<String>>();
|
List<List<String>> newStrings = new ArrayList<List<String>>();
|
||||||
for (int i = 0; i < numberOfTimes; i++) {
|
for (int i = 0; i < numberOfTimes; i++) {
|
||||||
@ -179,13 +207,15 @@ class TestStringDeduplicationTools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean waitForDeduplication(String s1, String s2) {
|
private static void waitForDeduplication(String s1, String s2) {
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
int timeout = 10000; // 10sec in ms
|
int timeout = 10000; // 10sec in ms
|
||||||
int iterationWait = 100; // 100ms
|
int iterationWait = 100; // 100ms
|
||||||
|
List<Optional<Double>> loadHistory = new ArrayList<>();
|
||||||
for (int attempts = 0; attempts < (timeout / iterationWait); attempts++) {
|
for (int attempts = 0; attempts < (timeout / iterationWait); attempts++) {
|
||||||
|
loadHistory.add(systemLoad());
|
||||||
if (getValue(s1) == getValue(s2)) {
|
if (getValue(s1) == getValue(s2)) {
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
if (first) {
|
if (first) {
|
||||||
System.out.println("Waiting for deduplication...");
|
System.out.println("Waiting for deduplication...");
|
||||||
@ -194,10 +224,10 @@ class TestStringDeduplicationTools {
|
|||||||
try {
|
try {
|
||||||
Thread.sleep(iterationWait);
|
Thread.sleep(iterationWait);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException("Deduplication has not occurred: Thread.sleep() threw", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
throw new RuntimeException("Deduplication has not occurred, load history: " + minMax(loadHistory));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String generateString(int id) {
|
private static String generateString(int id) {
|
||||||
@ -240,7 +270,9 @@ class TestStringDeduplicationTools {
|
|||||||
*/
|
*/
|
||||||
private static void verifyStrings(ArrayList<String> list, int uniqueExpected) {
|
private static void verifyStrings(ArrayList<String> list, int uniqueExpected) {
|
||||||
boolean passed = false;
|
boolean passed = false;
|
||||||
|
List<Optional<Double>> loadHistory = new ArrayList<>();
|
||||||
for (int attempts = 0; attempts < 10; attempts++) {
|
for (int attempts = 0; attempts < 10; attempts++) {
|
||||||
|
loadHistory.add(systemLoad());
|
||||||
// Check number of deduplicated strings
|
// Check number of deduplicated strings
|
||||||
ArrayList<Object> unique = new ArrayList<Object>(uniqueExpected);
|
ArrayList<Object> unique = new ArrayList<Object>(uniqueExpected);
|
||||||
for (String string: list) {
|
for (String string: list) {
|
||||||
@ -277,7 +309,7 @@ class TestStringDeduplicationTools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!passed) {
|
if (!passed) {
|
||||||
throw new RuntimeException("String verification failed");
|
throw new RuntimeException("String verification failed, load history: " + minMax(loadHistory));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,9 +393,7 @@ class TestStringDeduplicationTools {
|
|||||||
// and be inserted into the deduplication hashtable.
|
// and be inserted into the deduplication hashtable.
|
||||||
forceDeduplication(ageThreshold, FullGC);
|
forceDeduplication(ageThreshold, FullGC);
|
||||||
|
|
||||||
if (!waitForDeduplication(dupString1, baseString)) {
|
waitForDeduplication(dupString1, baseString);
|
||||||
throw new RuntimeException("Deduplication has not occurred");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new duplicate of baseString
|
// Create a new duplicate of baseString
|
||||||
StringBuilder sb2 = new StringBuilder(baseString);
|
StringBuilder sb2 = new StringBuilder(baseString);
|
||||||
@ -398,9 +428,7 @@ class TestStringDeduplicationTools {
|
|||||||
|
|
||||||
forceDeduplication(ageThreshold, FullGC);
|
forceDeduplication(ageThreshold, FullGC);
|
||||||
|
|
||||||
if (!waitForDeduplication(dupString3, internedString)) {
|
waitForDeduplication(dupString3, internedString);
|
||||||
throw new RuntimeException("Deduplication has not occurred for string 3");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (afterInternedValue != getValue(dupString2)) {
|
if (afterInternedValue != getValue(dupString2)) {
|
||||||
throw new RuntimeException("Interned string value changed");
|
throw new RuntimeException("Interned string value changed");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user