Hi Mandy,
Could you please sponsor this attached patch.
It has been updated with all review comments.
jcheck is ok, except for missing reviewer.
webrev: http://cr.openjdk.java.net/~ykantser/8030628/webrev.04
bug: https://bugs.openjdk.java.net/browse/JDK-8030628
repositry: http://hg.openjdk.java.net/jdk9/dev/jdk
Mattias
----- Original Message -----
From: [email protected]
To: [email protected]
Sent: Friday, April 4, 2014 2:12:51 PM GMT +01:00 Amsterdam / Berlin / Bern /
Rome / Stockholm / Vienna
Subject: Re: RFR 8030628: MemoryMXBean/CollectionUsageThreshold.java is not
applicable for VM SQE testing
Hi,
I have updated the patch with the following changes:
Util.java line 130 - Moved Pattern from function to "private static final"
RunUtil.java line 64 - Use diamond operator.
webrev: http://cr.openjdk.java.net/~ykantser/8030628/webrev.04
I have created an enhancement for porting the other
shell scripts to java (https://bugs.openjdk.java.net/browse/JDK-8039257)
Mattias
----- Original Message -----
From: [email protected]
To: [email protected]
Cc: [email protected]
Sent: Wednesday, April 2, 2014 12:22:43 AM GMT +01:00 Amsterdam / Berlin / Bern
/ Rome / Stockholm / Vienna
Subject: Re: RFR 8030628: MemoryMXBean/CollectionUsageThreshold.java is not
applicable for VM SQE testing
Hi Mattias,
On 4/1/14 3:11 AM, Mattias Tobiasson wrote:
> Hi Mandy,
> I have moved the common code to a new utility class.
Thanks for the refactoring. Looks much better.
Nit: RunUtil.java line 64 - you can use diamond operator. No need to
generate a new webrev.
>
> The shell script tests work as they are, they do not fail.
> The reason for this is that they only use the default options specified in
> ${TESTVMOPTS}, not in ${TESTJAVAOPTS}.
> Any default GC options will be in ${TESTJAVAOPTS}, so they are ignored by the
> shell script tests.
> We may want to move the shell scripts to java later, but I think we should
> wait until we get the "@requires" tag in jtreg.
Can you file a bug to replace the shell script tests with the new
RunUtil class? @requires could be done independent with the shell
script test conversion.
thanks
Mandy
> webrev: http://cr.openjdk.java.net/~ykantser/8030628/webrev.03
> bug: https://bugs.openjdk.java.net/browse/JDK-8030628
>
> Mattias
>
> ----- Original Message -----
> From: [email protected]
> To: [email protected], [email protected]
> Cc: [email protected]
> Sent: Wednesday, March 19, 2014 6:45:27 PM GMT +01:00 Amsterdam / Berlin /
> Bern / Rome / Stockholm / Vienna
> Subject: Re: RFR 8030628: MemoryMXBean/CollectionUsageThreshold.java is not
> applicable for VM SQE testing
>
> Hi Mattias,
>
> On 3/14/2014 6:21 AM, Mattias Tobiasson wrote:
>> Hi,
>> I have updated the patch to include all failing tests for this bug.
>>
>> The tests currently fail because their GC options collide with GC options
>> from the test framework.
>> The fix will launch the tests in a separate JVM with controlled GC options.
>>
>> webrev: http://cr.openjdk.java.net/~ykantser/8030628/webrev.02
>> bug: https://bugs.openjdk.java.net/browse/JDK-8030628
> Thanks for updating other failing tests. I think we are not sure when
> the proper configuration support is in place and this temporary solution
> to allow the tests to run is reasonable.
>
> It'd be better to refactor the common code to launch the test with all
> GC configurations shared by jdk/test/java/lang/management/MemoryMXBean
> tests.
>
> There are other shell tests that can be removed if the corresponding
> java tests are modified to use your utility class. It's probably out
> of the scope of this fix. Do you have cycles to clean them up as well?
> They probably fail in VM nightlies like the ones you fixed if it
> overrides with a different GC.
>
> LowMemoryTest2.sh
> MemoryManagementParallelGC.sh
> MemoryManagementConcMarkSweepGC.sh
> MemoryManagementSerialGC.sh
> PendingAllGC.sh
>
> Mandy
>
>> Mattias
>>
>>
>> ----- Original Message -----
>> From: [email protected]
>> To: [email protected]
>> Cc: [email protected], [email protected],
>> [email protected]
>> Sent: Wednesday, March 12, 2014 10:19:08 AM GMT +01:00 Amsterdam / Berlin /
>> Bern / Rome / Stockholm / Vienna
>> Subject: Re: RFR 8030628: MemoryMXBean/CollectionUsageThreshold.java is not
>> applicable for VM SQE testing
>>
>> Hi Mandy,
>> I have talked to Leonid Mesnik, and he says there are plans for a jtreg flag
>> that would solve this problem in a general way (maybe @requires). I do not
>> know the time plan for that jtreg feature. The test currently fails in
>> nightlies, so we need a temporary fix.
>>
>> I don't know when/if all different GC configurations are used in nightly
>> tests. But for these tests that depend on the GC, I think it's good to
>> always run with different GC configurations. The test is fast so all 4 runs
>> take about a second.
>>
>> I did not notice that there are more tests in the same dir. I will change
>> them too.
>>
>> Mattias
>>
>> ----- Original Message -----
>> From: [email protected]
>> To: [email protected], [email protected],
>> [email protected]
>> Sent: Tuesday, March 11, 2014 8:48:04 PM GMT +01:00 Amsterdam / Berlin /
>> Bern / Rome / Stockholm / Vienna
>> Subject: Re: RFR 8030628: MemoryMXBean/CollectionUsageThreshold.java is not
>> applicable for VM SQE testing
>>
>> Hi Mattias,
>>
>> Have you discussed with Jon Gibbons about the jtreg @requires support?
>> I thought it was partly motivated by the requirement to specify a test
>> to run in different collector.
>>
>> The reason why these regression tests explicitly specifies different GC
>> flags was to increase the coverage and ensure to catch regression early
>> during development cycle. At that time, the VM nightly testing rotates
>> the test execution with different GC configuration that delayed to catch
>> a regression that occurs in one collector while the nightly testing is
>> testing another collector. For integration, I don't recall if different
>> collectors are tested rather than default. It may be time to revisit
>> the test execution with different collectors. If the verification of
>> different collectors is well covered in nightly, perhaps these tests no
>> longer need one @run per each collector.
>>
>> There are other regression tests that specifies the -XX:+UseXXGC flag in
>> the @run tag. It makes sense to modify them in the same patch (perhaps
>> at least tests under test/java/lang/management).
>>
>> Mandy
>>
>> On 3/11/14 6:15 AM, Mattias Tobiasson wrote:
>>> Hi,
>>> Could you please review this test fix.
>>>
>>> The test fails because it specifies its own GC command line options, for
>>> example:
>>> @run main/othervm/timeout=300 -XX:+PrintGCDetails -XX:+UseSerialGC
>>> CollectionUsageThreshold
>>>
>>> When the framework also specifies GC version, then the test will fail with
>>> this log:
>>> "Conflicting collector combinations in option list; Error: Could not create
>>> the Java Virtual Machine."
>>>
>>> The solution is to run the test in a separate JVM with controlled GC
>>> options.
>>> The test will be run multiple times.
>>> First with the command line specified from the framework, without test
>>> specific GC options.
>>> Then once for each GC version specified in the test. When the test
>>> specifies the GC, any GC options from the framework are removed.
>>>
>>> webrev: http://cr.openjdk.java.net/~ykantser/8030628/webrev.01
>>> bug: https://bugs.openjdk.java.net/browse/JDK-8030628
>>>
>>> Mattias
>>>
# HG changeset patch
# User mtobiass
# Date 1396604491 -7200
# Node ID 8ca451a7d41d8add5529cec32e17b85b585bb5f0
# Parent a73632def4069afe395e0b99601ff4fa5c08a5a8
8030628: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java is not applicable for VM SQE testing
Summary: Run tests in separate JVM with controlled GC command line options.
diff --git a/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java b/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java
--- a/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java
+++ b/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java
@@ -30,11 +30,9 @@
*
* @author Mandy Chung
*
- * @build CollectionUsageThreshold MemoryUtil
- * @run main/othervm/timeout=300 -XX:+PrintGCDetails -XX:+UseSerialGC CollectionUsageThreshold
- * @run main/othervm/timeout=300 -XX:+PrintGCDetails -XX:+UseParallelGC CollectionUsageThreshold
- * @run main/othervm/timeout=300 -XX:+PrintGCDetails -XX:+UseG1GC CollectionUsageThreshold
- * @run main/othervm/timeout=300 -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC CollectionUsageThreshold
+ * @library /lib/testlibrary/
+ * @build CollectionUsageThreshold MemoryUtil RunUtil
+ * @run main/timeout=300 CollectionUsageThreshold
*/
import java.util.*;
@@ -61,6 +59,20 @@
// finishes checking the low memory notification result
private static final CyclicBarrier barrier = new CyclicBarrier(2);
+ /**
+ * Run the test multiple times with different GC versions.
+ * First with default command line specified by the framework.
+ * Then with GC versions specified by the test.
+ */
+ public static void main(String a[]) throws Throwable {
+ final String main = "CollectionUsageThreshold$TestMain";
+ RunUtil.runTestKeepGcOpts(main);
+ RunUtil.runTestClearGcOpts(main, "-XX:+UseSerialGC");
+ RunUtil.runTestClearGcOpts(main, "-XX:+UseParallelGC");
+ RunUtil.runTestClearGcOpts(main, "-XX:+UseG1GC");
+ RunUtil.runTestClearGcOpts(main, "-XX:+UseConcMarkSweepGC");
+ }
+
static class PoolRecord {
private final MemoryPoolMXBean pool;
private final AtomicInteger listenerInvoked = new AtomicInteger(0);
@@ -110,88 +122,90 @@
}
}
- public static void main(String args[]) throws Exception {
- if (args.length > 0 && args[0].equals("trace")) {
- trace = true;
+ private static class TestMain {
+ public static void main(String args[]) throws Exception {
+ if (args.length > 0 && args[0].equals("trace")) {
+ trace = true;
+ }
+
+ List<MemoryPoolMXBean> pools = getMemoryPoolMXBeans();
+ List<MemoryManagerMXBean> managers = getMemoryManagerMXBeans();
+
+ if (trace) {
+ MemoryUtil.printMemoryPools(pools);
+ MemoryUtil.printMemoryManagers(managers);
+ }
+
+ // Find the Old generation which supports low memory detection
+ for (MemoryPoolMXBean p : pools) {
+ if (p.isUsageThresholdSupported() && p.isCollectionUsageThresholdSupported()) {
+ if (p.getName().toLowerCase().contains("perm")) {
+ // if we have a "perm gen" pool increase the number of expected
+ // memory pools by one.
+ numMemoryPools++;
+ }
+ PoolRecord pr = new PoolRecord(p);
+ result.put(p.getName(), pr);
+ if (result.size() == numMemoryPools) {
+ break;
+ }
+ }
+ }
+ if (result.size() != numMemoryPools) {
+ throw new RuntimeException("Unexpected number of selected pools");
+ }
+
+ try {
+ // This test creates a checker thread responsible for checking
+ // the low memory notifications. It blocks until a permit
+ // from the signals semaphore is available.
+ Checker checker = new Checker("Checker thread");
+ checker.setDaemon(true);
+ checker.start();
+
+ for (PoolRecord pr : result.values()) {
+ pr.getPool().setCollectionUsageThreshold(THRESHOLD);
+ System.out.println("Collection usage threshold of " +
+ pr.getPool().getName() + " set to " + THRESHOLD);
+ }
+
+ SensorListener listener = new SensorListener();
+ NotificationEmitter emitter = (NotificationEmitter) mm;
+ emitter.addNotificationListener(listener, null, null);
+
+ // The main thread invokes GC to trigger the VM to perform
+ // low memory detection and then waits until the checker thread
+ // finishes its work to check for a low-memory notification.
+ //
+ // At GC time, VM will issue low-memory notification and invoke
+ // the listener which will release a permit to the signals semaphore.
+ // When the checker thread acquires the permit and finishes
+ // checking the low-memory notification, it will also call
+ // barrier.await() to signal the main thread to resume its work.
+ for (int i = 0; i < NUM_GCS; i++) {
+ invokeGC();
+ barrier.await();
+ }
+ } finally {
+ // restore the default
+ for (PoolRecord pr : result.values()) {
+ pr.getPool().setCollectionUsageThreshold(0);
+ }
+ }
+ System.out.println(RunUtil.successMessage);
}
- List<MemoryPoolMXBean> pools = getMemoryPoolMXBeans();
- List<MemoryManagerMXBean> managers = getMemoryManagerMXBeans();
- if (trace) {
- MemoryUtil.printMemoryPools(pools);
- MemoryUtil.printMemoryManagers(managers);
- }
+ private static void invokeGC() {
+ System.out.println("Calling System.gc()");
+ numGCs++;
+ mm.gc();
- // Find the Old generation which supports low memory detection
- for (MemoryPoolMXBean p : pools) {
- if (p.isUsageThresholdSupported() && p.isCollectionUsageThresholdSupported()) {
- if (p.getName().toLowerCase().contains("perm")) {
- // if we have a "perm gen" pool increase the number of expected
- // memory pools by one.
- numMemoryPools++;
+ if (trace) {
+ for (PoolRecord pr : result.values()) {
+ System.out.println("Usage after GC for: " + pr.getPool().getName());
+ MemoryUtil.printMemoryUsage(pr.getPool().getUsage());
}
- PoolRecord pr = new PoolRecord(p);
- result.put(p.getName(), pr);
- if (result.size() == numMemoryPools) {
- break;
- }
- }
- }
- if (result.size() != numMemoryPools) {
- throw new RuntimeException("Unexpected number of selected pools");
- }
-
- try {
- // This test creates a checker thread responsible for checking
- // the low memory notifications. It blocks until a permit
- // from the signals semaphore is available.
- Checker checker = new Checker("Checker thread");
- checker.setDaemon(true);
- checker.start();
-
- for (PoolRecord pr : result.values()) {
- pr.getPool().setCollectionUsageThreshold(THRESHOLD);
- System.out.println("Collection usage threshold of " +
- pr.getPool().getName() + " set to " + THRESHOLD);
- }
-
- SensorListener listener = new SensorListener();
- NotificationEmitter emitter = (NotificationEmitter) mm;
- emitter.addNotificationListener(listener, null, null);
-
- // The main thread invokes GC to trigger the VM to perform
- // low memory detection and then waits until the checker thread
- // finishes its work to check for a low-memory notification.
- //
- // At GC time, VM will issue low-memory notification and invoke
- // the listener which will release a permit to the signals semaphore.
- // When the checker thread acquires the permit and finishes
- // checking the low-memory notification, it will also call
- // barrier.await() to signal the main thread to resume its work.
- for (int i = 0; i < NUM_GCS; i++) {
- invokeGC();
- barrier.await();
- }
- } finally {
- // restore the default
- for (PoolRecord pr : result.values()) {
- pr.getPool().setCollectionUsageThreshold(0);
- }
- }
- System.out.println("Test passed.");
- }
-
-
- private static void invokeGC() {
- System.out.println("Calling System.gc()");
- numGCs++;
- mm.gc();
-
- if (trace) {
- for (PoolRecord pr : result.values()) {
- System.out.println("Usage after GC for: " + pr.getPool().getName());
- MemoryUtil.printMemoryUsage(pr.getPool().getUsage());
}
}
}
diff --git a/test/java/lang/management/MemoryMXBean/LowMemoryTest.java b/test/java/lang/management/MemoryMXBean/LowMemoryTest.java
--- a/test/java/lang/management/MemoryMXBean/LowMemoryTest.java
+++ b/test/java/lang/management/MemoryMXBean/LowMemoryTest.java
@@ -30,11 +30,9 @@
*
* @author Mandy Chung
*
- * @build LowMemoryTest MemoryUtil
- * @run main/othervm/timeout=600 LowMemoryTest
- * @run main/othervm/timeout=600 -XX:+UseConcMarkSweepGC LowMemoryTest
- * @run main/othervm/timeout=600 -XX:+UseParallelGC LowMemoryTest
- * @run main/othervm/timeout=600 -XX:+UseSerialGC LowMemoryTest
+ * @library /lib/testlibrary/
+ * @build LowMemoryTest MemoryUtil RunUtil
+ * @run main/timeout=600 LowMemoryTest
*/
import java.lang.management.*;
@@ -54,6 +52,20 @@
private static final int NUM_CHUNKS = 2;
private static long chunkSize;
+ /**
+ * Run the test multiple times with different GC versions.
+ * First with default command line specified by the framework.
+ * Then with GC versions specified by the test.
+ */
+ public static void main(String a[]) throws Throwable {
+ final String main = "LowMemoryTest$TestMain";
+ RunUtil.runTestKeepGcOpts(main);
+ RunUtil.runTestClearGcOpts(main, "-XX:+UseSerialGC");
+ RunUtil.runTestClearGcOpts(main, "-XX:+UseParallelGC");
+ RunUtil.runTestClearGcOpts(main, "-XX:+UseG1GC");
+ RunUtil.runTestClearGcOpts(main, "-XX:+UseConcMarkSweepGC");
+ }
+
private static volatile boolean listenerInvoked = false;
static class SensorListener implements NotificationListener {
@Override
@@ -107,77 +119,80 @@
}
private static long newThreshold;
- public static void main(String args[]) throws Exception {
- if (args.length > 0 && args[0].equals("trace")) {
- trace = true;
- }
- // Find the Old generation which supports low memory detection
- ListIterator iter = pools.listIterator();
- while (iter.hasNext()) {
- MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();
- if (p.getType() == MemoryType.HEAP &&
+ private static class TestMain {
+ public static void main(String args[]) throws Exception {
+ if (args.length > 0 && args[0].equals("trace")) {
+ trace = true;
+ }
+
+ // Find the Old generation which supports low memory detection
+ ListIterator iter = pools.listIterator();
+ while (iter.hasNext()) {
+ MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();
+ if (p.getType() == MemoryType.HEAP &&
p.isUsageThresholdSupported()) {
- mpool = p;
- if (trace) {
- System.out.println("Selected memory pool for low memory " +
- "detection.");
- MemoryUtil.printMemoryPool(mpool);
+ mpool = p;
+ if (trace) {
+ System.out.println("Selected memory pool for low memory " +
+ "detection.");
+ MemoryUtil.printMemoryPool(mpool);
+ }
+ break;
}
- break;
}
- }
- TestListener listener = new TestListener();
- SensorListener l2 = new SensorListener();
- NotificationEmitter emitter = (NotificationEmitter) mm;
- emitter.addNotificationListener(listener, null, null);
- emitter.addNotificationListener(l2, null, null);
+ TestListener listener = new TestListener();
+ SensorListener l2 = new SensorListener();
+ NotificationEmitter emitter = (NotificationEmitter) mm;
+ emitter.addNotificationListener(listener, null, null);
+ emitter.addNotificationListener(l2, null, null);
- Thread allocator = new AllocatorThread();
- Thread sweeper = new SweeperThread();
+ Thread allocator = new AllocatorThread();
+ Thread sweeper = new SweeperThread();
- // Now set threshold
- MemoryUsage mu = mpool.getUsage();
- chunkSize = (mu.getMax() - mu.getUsed()) / 20;
- newThreshold = mu.getUsed() + (chunkSize * NUM_CHUNKS);
+ // Now set threshold
+ MemoryUsage mu = mpool.getUsage();
+ chunkSize = (mu.getMax() - mu.getUsed()) / 20;
+ newThreshold = mu.getUsed() + (chunkSize * NUM_CHUNKS);
- System.out.println("Setting threshold for " + mpool.getName() +
- " from " + mpool.getUsageThreshold() + " to " + newThreshold +
- ". Current used = " + mu.getUsed());
- mpool.setUsageThreshold(newThreshold);
+ System.out.println("Setting threshold for " + mpool.getName() +
+ " from " + mpool.getUsageThreshold() + " to " + newThreshold +
+ ". Current used = " + mu.getUsed());
+ mpool.setUsageThreshold(newThreshold);
- if (mpool.getUsageThreshold() != newThreshold) {
- throw new RuntimeException("TEST FAILED: " +
+ if (mpool.getUsageThreshold() != newThreshold) {
+ throw new RuntimeException("TEST FAILED: " +
"Threshold for Memory pool " + mpool.getName() +
"is " + mpool.getUsageThreshold() + " but expected to be" +
newThreshold);
+ }
+
+
+ allocator.start();
+ // Force Allocator start first
+ phaser.arriveAndAwaitAdvance();
+ sweeper.start();
+
+
+ try {
+ allocator.join();
+ // Wait until AllocatorThread's done
+ phaser.arriveAndAwaitAdvance();
+ sweeper.join();
+ } catch (InterruptedException e) {
+ System.out.println("Unexpected exception:" + e);
+ testFailed = true;
+ }
+
+ listener.checkResult();
+
+ if (testFailed)
+ throw new RuntimeException("TEST FAILED.");
+
+ System.out.println(RunUtil.successMessage);
+
}
-
-
- allocator.start();
- // Force Allocator start first
- phaser.arriveAndAwaitAdvance();
- sweeper.start();
-
-
- try {
- allocator.join();
- // Wait until AllocatorThread's done
- phaser.arriveAndAwaitAdvance();
- sweeper.join();
- } catch (InterruptedException e) {
- System.out.println("Unexpected exception:" + e);
- testFailed = true;
- }
-
- listener.checkResult();
-
- if (testFailed)
- throw new RuntimeException("TEST FAILED.");
-
- System.out.println("Test passed.");
-
}
private static void goSleep(long ms) {
diff --git a/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java b/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java
--- a/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java
+++ b/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java
@@ -32,11 +32,9 @@
* @summary Basic Test for MemoryPool.resetPeakUsage()
* @author Mandy Chung
*
- * @build ResetPeakMemoryUsage MemoryUtil
- * @run main/othervm -XX:+PrintGCDetails -XX:+UseSerialGC -Xms256m -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage
- * @run main/othervm -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -Xms256m -Xmn8m ResetPeakMemoryUsage
- * @run main/othervm -XX:+PrintGCDetails -XX:+UseParallelGC -Xms256m -Xmn8m ResetPeakMemoryUsage
- * @run main/othervm -XX:+PrintGCDetails -XX:+UseG1GC -Xms256m -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage
+ * @library /lib/testlibrary/
+ * @build ResetPeakMemoryUsage MemoryUtil RunUtil
+ * @run main ResetPeakMemoryUsage
*/
import java.lang.management.*;
@@ -47,24 +45,42 @@
// make public so that it can't be optimized away easily
public static Object[] obj;
- public static void main(String[] argv) {
- List pools = ManagementFactory.getMemoryPoolMXBeans();
- ListIterator iter = pools.listIterator();
- boolean found = false;
- while (iter.hasNext()) {
- MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();
- // only check heap pools that support usage threshold
- // this is typically only the old generation space
- // since the other spaces are expected to get filled up
- if (p.getType() == MemoryType.HEAP &&
- p.isUsageThresholdSupported())
- {
- found = true;
- testPool(p);
+ /**
+ * Run the test multiple times with different GC versions.
+ * First with default command line specified by the framework.
+ * Then with all GC versions specified by the test.
+ */
+ public static void main(String a[]) throws Throwable {
+ final String main = "ResetPeakMemoryUsage$TestMain";
+ final String ms = "-Xms256m";
+ final String mn = "-Xmn8m";
+ RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseConcMarkSweepGC");
+ RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseParallelGC");
+ RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseG1GC", "-XX:G1HeapRegionSize=1m");
+ RunUtil.runTestClearGcOpts(main, ms, mn, "-XX:+UseSerialGC",
+ "-XX:MarkSweepAlwaysCompactCount=1");
+ }
+
+ private static class TestMain {
+ public static void main(String[] argv) {
+ List pools = ManagementFactory.getMemoryPoolMXBeans();
+ ListIterator iter = pools.listIterator();
+ boolean found = false;
+ while (iter.hasNext()) {
+ MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();
+ // only check heap pools that support usage threshold
+ // this is typically only the old generation space
+ // since the other spaces are expected to get filled up
+ if (p.getType() == MemoryType.HEAP &&
+ p.isUsageThresholdSupported())
+ {
+ found = true;
+ testPool(p);
+ }
}
- }
- if (!found) {
- throw new RuntimeException("No heap pool found");
+ if (!found) {
+ throw new RuntimeException("No heap pool found");
+ }
}
}
@@ -142,7 +158,7 @@
formatSize("previous peak", peak2.getUsed()));
}
- System.out.println("Test passed.");
+ System.out.println(RunUtil.successMessage);
}
private static String INDENT = " ";
diff --git a/test/java/lang/management/MemoryMXBean/RunUtil.java b/test/java/lang/management/MemoryMXBean/RunUtil.java
new file mode 100644
--- /dev/null
+++ b/test/java/lang/management/MemoryMXBean/RunUtil.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Utility class for launching a test in a separate JVM.
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.Utils;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JDKToolFinder;
+
+public class RunUtil {
+
+ // Used to mark that the test has passed successfully.
+ public static final String successMessage = "Test passed.";
+
+ public static void runTestClearGcOpts(String main, String... testOpts) throws Throwable {
+ runTest(main, true, testOpts);
+ }
+
+ public static void runTestKeepGcOpts(String main, String... testOpts) throws Throwable {
+ runTest(main, false, testOpts);
+ }
+
+ /**
+ * Runs a test in a separate JVM.
+ * command line like:
+ * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
+ *
+ * {defaultopts} are the default java options set by the framework.
+ * Default GC options in {defaultopts} may be removed.
+ * This is used when the test specifies its own GC options.
+ *
+ * @param main Name of the main class.
+ * @param clearGcOpts true if the default GC options should be removed.
+ * @param testOpts java options specified by the test.
+ */
+ private static void runTest(String main, boolean clearGcOpts, String... testOpts)
+ throws Throwable {
+ List<String> opts = new ArrayList<>();
+ opts.add(JDKToolFinder.getJDKTool("java"));
+ opts.addAll(Arrays.asList(Utils.getTestJavaOpts()));
+ opts.add("-cp");
+ opts.add(System.getProperty("test.class.path", "test.class.path"));
+ opts.add("-XX:+PrintGCDetails");
+
+ if (clearGcOpts) {
+ opts = Utils.removeGcOpts(opts);
+ }
+ opts.addAll(Arrays.asList(testOpts));
+ opts.add(main);
+
+ OutputAnalyzer output = ProcessTools.executeProcess(opts.toArray(new String[0]));
+ output.shouldHaveExitValue(0);
+ if (output.getStdout().indexOf(successMessage) < 0) {
+ throw new Exception("output missing '" + successMessage + "'");
+ }
+ }
+
+}
diff --git a/test/lib/testlibrary/jdk/testlibrary/Utils.java b/test/lib/testlibrary/jdk/testlibrary/Utils.java
--- a/test/lib/testlibrary/jdk/testlibrary/Utils.java
+++ b/test/lib/testlibrary/jdk/testlibrary/Utils.java
@@ -120,6 +120,26 @@
}
/**
+ * Removes any options specifying which GC to use, for example "-XX:+UseG1GC".
+ * Removes any options matching: -XX:(+/-)Use*GC
+ * Used when a test need to set its own GC version. Then any
+ * GC specified by the framework must first be removed.
+ * @return A copy of given opts with all GC options removed.
+ */
+ private static final Pattern useGcPattern = Pattern.compile("\\-XX\\:[\\+\\-]Use.+GC");
+ public static List<String> removeGcOpts(List<String> opts) {
+ List<String> optsWithoutGC = new ArrayList<String>();
+ for (String opt : opts) {
+ if (useGcPattern.matcher(opt).matches()) {
+ System.out.println("removeGcOpts: removed " + opt);
+ } else {
+ optsWithoutGC.add(opt);
+ }
+ }
+ return optsWithoutGC;
+ }
+
+ /**
* Splits a string by white space.
* Works like String.split(), but returns an empty array
* if the string is null or empty.