158 lines
5.5 KiB
Diff
158 lines
5.5 KiB
Diff
From 9b431c9bba018a2dd2bb6850cfd674b51207bf49 Mon Sep 17 00:00:00 2001
|
|
Date: Thu, 19 Oct 2023 01:37:43 +0000
|
|
Subject: [PATCH 3/5] change value of GCLockerRetryAllocationCount from 2 to
|
|
1000 to avoid OOM
|
|
|
|
---
|
|
hotspot/src/share/vm/runtime/globals.hpp | 2 +-
|
|
.../g1/TestGcLockerEvacFailureThreaded.java | 124 ++++++++++++++++++
|
|
2 files changed, 125 insertions(+), 1 deletion(-)
|
|
create mode 100644 hotspot/test/gc/g1/TestGcLockerEvacFailureThreaded.java
|
|
|
|
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
|
|
index fdd9db149..65806a475 100644
|
|
--- a/hotspot/src/share/vm/runtime/globals.hpp
|
|
+++ b/hotspot/src/share/vm/runtime/globals.hpp
|
|
@@ -1575,7 +1575,7 @@ class CommandLineFlags {
|
|
"How much the GC can expand the eden by while the GC locker " \
|
|
"is active (as a percentage)") \
|
|
\
|
|
- diagnostic(uintx, GCLockerRetryAllocationCount, 2, \
|
|
+ diagnostic(uintx, GCLockerRetryAllocationCount, 1000, \
|
|
"Number of times to retry allocations when " \
|
|
"blocked by the GC locker") \
|
|
\
|
|
diff --git a/hotspot/test/gc/g1/TestGcLockerEvacFailureThreaded.java b/hotspot/test/gc/g1/TestGcLockerEvacFailureThreaded.java
|
|
new file mode 100644
|
|
index 000000000..74accd951
|
|
--- /dev/null
|
|
+++ b/hotspot/test/gc/g1/TestGcLockerEvacFailureThreaded.java
|
|
@@ -0,0 +1,124 @@
|
|
+import java.io.ByteArrayOutputStream;
|
|
+import java.io.IOException;
|
|
+import java.lang.ref.SoftReference;
|
|
+import java.nio.ByteBuffer;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+import java.util.Random;
|
|
+import java.util.zip.GZIPOutputStream;
|
|
+
|
|
+import com.oracle.java.testlibrary.ProcessTools;
|
|
+import com.oracle.java.testlibrary.OutputAnalyzer;
|
|
+
|
|
+/*
|
|
+ * @test TestGcLockerEvacFailureThreaded.java
|
|
+ * @bug 8048556 8137099
|
|
+ * @summary Ensure that GCLocker does not cause early program termination.
|
|
+ * @key gc
|
|
+ * @library /testlibrary
|
|
+ */
|
|
+public class TestGcLockerEvacFailureThreaded {
|
|
+ public static void main(String[] args) throws Exception {
|
|
+ System.out.println("Beginning test\n");
|
|
+
|
|
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
|
|
+ "-Xmx64m",
|
|
+ TestGcLocker.class.getName());
|
|
+
|
|
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
|
+
|
|
+ System.out.println("Output:\n" + output.getOutput());
|
|
+
|
|
+ output.shouldNotContain("java.lang.OutOfMemoryError");
|
|
+ output.shouldHaveExitValue(0);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Tests whether GCLocker terminates the application when forced to spin multiple times.
|
|
+ * We cause a long-running native call during which a GC is invoked by another thread.
|
|
+ */
|
|
+ static class TestGcLocker {
|
|
+
|
|
+ private static int gzipItemLengthBytes = 10500;
|
|
+ private static int nGzipItems = 3500;
|
|
+ private static int aliveDataItems = (int) (nGzipItems * 0.7);
|
|
+
|
|
+ private static int nThreads = 500;
|
|
+ private static int loopSize = 1000;
|
|
+
|
|
+ private static List<byte[]> dataToBeGzipped = new ArrayList<>(nGzipItems);
|
|
+
|
|
+ private static List<byte[]> aliveData = new ArrayList<>(aliveDataItems);
|
|
+
|
|
+ private static Random randomGenerator = new Random();
|
|
+
|
|
+ private static volatile boolean cont = true;
|
|
+
|
|
+ private static void createData(int gzipItemLengthBytes, int nGzipItems) throws IOException {
|
|
+ for (int gzipDataIndex = 0; gzipDataIndex < nGzipItems; gzipDataIndex++) {
|
|
+ ByteBuffer buffer = ByteBuffer.allocate(gzipItemLengthBytes);
|
|
+ for (int i = 0; i < gzipItemLengthBytes/4; i++) { // since integer is 4 bytes
|
|
+ int randomInt = randomGenerator.nextInt(100);
|
|
+ buffer.putInt(randomInt);
|
|
+ }
|
|
+ byte[] data = buffer.array();
|
|
+ dataToBeGzipped.add(data);
|
|
+ }
|
|
+
|
|
+ for (int i = 0; i < aliveDataItems; i++) {
|
|
+ aliveData.add(new byte[0]);
|
|
+ }
|
|
+
|
|
+ for (int gzipDataIndex = 0; gzipDataIndex < nGzipItems; gzipDataIndex++) {
|
|
+ native_critical_section(dataToBeGzipped.get(gzipDataIndex));
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ public static void runTest(int loopSize) {
|
|
+ try {
|
|
+ int i = 0;
|
|
+ while (cont && (i < loopSize)) {
|
|
+ i++;
|
|
+ try {
|
|
+ native_critical_section(dataToBeGzipped.get(i % nGzipItems));
|
|
+ } catch (OutOfMemoryError e) {
|
|
+ cont = false; //Remove this if you still want to continue after OOME
|
|
+ e.printStackTrace();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ } catch (IOException e) {
|
|
+ cont = true;
|
|
+ e.printStackTrace();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static void native_critical_section(byte[] data) throws IOException {
|
|
+ try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); GZIPOutputStream gzos = new GZIPOutputStream(bos)) {
|
|
+ gzos.write(data);
|
|
+ gzos.finish();
|
|
+ byte[] compressedData = bos.toByteArray();
|
|
+ int index = randomGenerator.nextInt(aliveDataItems);
|
|
+ aliveData.set(index, compressedData);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static void main(String[] args) throws InterruptedException, IOException {
|
|
+ createData(gzipItemLengthBytes, nGzipItems);
|
|
+
|
|
+ System.gc(); //This will tell us the resident set size
|
|
+
|
|
+ for (int i = 0; i < nThreads; i++) {
|
|
+ Thread t = new Thread() {
|
|
+ public void run() {
|
|
+ runTest(loopSize);
|
|
+ }
|
|
+ };
|
|
+ t.start();
|
|
+ }
|
|
+ System.out.println("Threads started");
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
--
|
|
2.19.1
|
|
|