8248266: ZGC: TestUncommit.java fails due to "Exception: Uncommitted too fast" again
Reviewed-by: shade, eosterlund
This commit is contained in:
parent
f779affda0
commit
e8d284faac
src/hotspot/share/gc/z
test/hotspot/jtreg/gc/z
@ -159,7 +159,7 @@ inline uint64_t ZPage::last_used() const {
|
||||
}
|
||||
|
||||
inline void ZPage::set_last_used() {
|
||||
_last_used = os::elapsedTime();
|
||||
_last_used = ceil(os::elapsedTime());
|
||||
}
|
||||
|
||||
inline bool ZPage::is_in(uintptr_t addr) const {
|
||||
|
@ -330,7 +330,7 @@ size_t ZPageCache::flush_for_uncommit(size_t requested, ZList<ZPage>* to, uint64
|
||||
}
|
||||
|
||||
void ZPageCache::set_last_commit() {
|
||||
_last_commit = os::elapsedTime();
|
||||
_last_commit = ceil(os::elapsedTime());
|
||||
}
|
||||
|
||||
void ZPageCache::pages_do(ZPageClosure* cl) const {
|
||||
|
63
test/hotspot/jtreg/gc/z/TestNoUncommit.java
Normal file
63
test/hotspot/jtreg/gc/z/TestNoUncommit.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.
|
||||
*/
|
||||
|
||||
package gc.z;
|
||||
|
||||
/*
|
||||
* @test TestNoUncommit
|
||||
* @requires vm.gc.Z & !vm.graal.enabled
|
||||
* @summary Test ZGC uncommit unused memory disabled
|
||||
* @run main/othervm -XX:+UseZGC -Xlog:gc*,gc+heap=debug,gc+stats=off -Xms512M -Xmx512M -XX:ZUncommitDelay=1 gc.z.TestNoUncommit
|
||||
* @run main/othervm -XX:+UseZGC -Xlog:gc*,gc+heap=debug,gc+stats=off -Xms128M -Xmx512M -XX:ZUncommitDelay=1 -XX:-ZUncommit gc.z.TestNoUncommit
|
||||
*/
|
||||
|
||||
public class TestNoUncommit {
|
||||
private static final int allocSize = 200 * 1024 * 1024; // 200M
|
||||
private static volatile Object keepAlive = null;
|
||||
|
||||
private static long capacity() {
|
||||
return Runtime.getRuntime().totalMemory();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Allocating");
|
||||
keepAlive = new byte[allocSize];
|
||||
final var afterAlloc = capacity();
|
||||
|
||||
System.out.println("Reclaiming");
|
||||
keepAlive = null;
|
||||
System.gc();
|
||||
|
||||
// Wait longer than the uncommit delay (which is 1 second)
|
||||
Thread.sleep(5 * 1000);
|
||||
|
||||
final var afterDelay = capacity();
|
||||
|
||||
// Verify
|
||||
if (afterAlloc > afterDelay) {
|
||||
throw new Exception("Should not uncommit");
|
||||
}
|
||||
|
||||
System.out.println("Success");
|
||||
}
|
||||
}
|
@ -27,27 +27,15 @@ package gc.z;
|
||||
* @test TestUncommit
|
||||
* @requires vm.gc.Z
|
||||
* @summary Test ZGC uncommit unused memory
|
||||
* @run main/othervm -XX:+UseZGC -Xlog:gc*,gc+heap=debug,gc+stats=off -Xms128M -Xmx512M -XX:ZUncommitDelay=10 gc.z.TestUncommit true 2
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test TestUncommit
|
||||
* @requires vm.gc.Z
|
||||
* @summary Test ZGC uncommit unused memory
|
||||
* @run main/othervm -XX:+UseZGC -Xlog:gc*,gc+heap=debug,gc+stats=off -Xms512M -Xmx512M -XX:ZUncommitDelay=10 gc.z.TestUncommit false 1
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test TestUncommit
|
||||
* @requires vm.gc.Z
|
||||
* @summary Test ZGC uncommit unused memory
|
||||
* @run main/othervm -XX:+UseZGC -Xlog:gc*,gc+heap=debug,gc+stats=off -Xms128M -Xmx512M -XX:ZUncommitDelay=10 -XX:-ZUncommit gc.z.TestUncommit false 1
|
||||
* @library /test/lib
|
||||
* @run main/othervm -XX:+UseZGC -Xlog:gc*,gc+heap=debug,gc+stats=off -Xms128M -Xmx512M -XX:ZUncommitDelay=10 gc.z.TestUncommit
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
public class TestUncommit {
|
||||
private static final int delay = 10; // seconds
|
||||
private static final int delay = 10 * 1000; // milliseconds
|
||||
private static final int allocSize = 200 * 1024 * 1024; // 200M
|
||||
private static final int smallObjectSize = 4 * 1024; // 4K
|
||||
private static final int mediumObjectSize = 2 * 1024 * 1024; // 2M
|
||||
@ -55,6 +43,13 @@ public class TestUncommit {
|
||||
|
||||
private static volatile ArrayList<byte[]> keepAlive;
|
||||
|
||||
private static final long startTime = System.nanoTime();
|
||||
|
||||
private static void log(String msg) {
|
||||
final String elapsedSeconds = String.format("%.3fs", (System.nanoTime() - startTime) / 1_000_000_000.0);
|
||||
System.out.println("[" + elapsedSeconds + "] (" + Thread.currentThread().getName() + ") " + msg);
|
||||
}
|
||||
|
||||
private static long capacity() {
|
||||
return Runtime.getRuntime().totalMemory();
|
||||
}
|
||||
@ -71,71 +66,71 @@ public class TestUncommit {
|
||||
System.gc();
|
||||
}
|
||||
|
||||
private static void test(boolean enabled, int objectSize) throws Exception {
|
||||
private static void test(int objectSize) throws Exception {
|
||||
final var beforeAlloc = capacity();
|
||||
|
||||
// Allocate memory
|
||||
log("Allocating");
|
||||
allocate(objectSize);
|
||||
|
||||
final var timeAfterAlloc = System.nanoTime();
|
||||
final var afterAlloc = capacity();
|
||||
|
||||
// Reclaim memory
|
||||
log("Reclaiming");
|
||||
reclaim();
|
||||
|
||||
// Wait shorter than the uncommit delay
|
||||
Thread.sleep(delay * 1000 / 2);
|
||||
log("Waiting for uncommit to start");
|
||||
while (capacity() >= afterAlloc) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
final var beforeUncommit = capacity();
|
||||
log("Uncommit started");
|
||||
final var timeUncommitStart = System.nanoTime();
|
||||
final var actualDelay = (timeUncommitStart - timeAfterAlloc) / 1_000_000;
|
||||
|
||||
// Wait longer than the uncommit delay
|
||||
Thread.sleep(delay * 1000);
|
||||
log("Waiting for uncommit to complete");
|
||||
while (capacity() > beforeAlloc) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
log("Uncommit completed");
|
||||
final var afterUncommit = capacity();
|
||||
|
||||
System.out.println(" Uncommit Enabled: " + enabled);
|
||||
System.out.println(" Uncommit Delay: " + delay);
|
||||
System.out.println(" Object Size: " + objectSize);
|
||||
System.out.println(" Alloc Size: " + allocSize);
|
||||
System.out.println(" Before Alloc: " + beforeAlloc);
|
||||
System.out.println(" After Alloc: " + afterAlloc);
|
||||
System.out.println(" Before Uncommit: " + beforeUncommit);
|
||||
System.out.println(" After Uncommit: " + afterUncommit);
|
||||
System.out.println();
|
||||
log(" Uncommit Delay: " + delay);
|
||||
log(" Object Size: " + objectSize);
|
||||
log(" Alloc Size: " + allocSize);
|
||||
log(" Before Alloc: " + beforeAlloc);
|
||||
log(" After Alloc: " + afterAlloc);
|
||||
log(" After Uncommit: " + afterUncommit);
|
||||
log(" Actual Uncommit Delay: " + actualDelay);
|
||||
|
||||
// Verify
|
||||
if (enabled) {
|
||||
if (beforeUncommit == beforeAlloc) {
|
||||
throw new Exception("Uncommitted too fast");
|
||||
}
|
||||
|
||||
if (afterUncommit >= afterAlloc) {
|
||||
throw new Exception("Uncommitted too slow");
|
||||
}
|
||||
|
||||
if (afterUncommit < beforeAlloc) {
|
||||
throw new Exception("Uncommitted too much");
|
||||
}
|
||||
|
||||
if (afterUncommit > beforeAlloc) {
|
||||
throw new Exception("Uncommitted too little");
|
||||
}
|
||||
} else {
|
||||
if (afterAlloc > beforeUncommit ||
|
||||
afterAlloc > afterUncommit) {
|
||||
throw new Exception("Should not uncommit");
|
||||
}
|
||||
if (actualDelay < delay) {
|
||||
throw new Exception("Uncommitted too fast");
|
||||
}
|
||||
|
||||
if (actualDelay > delay * 2 * Utils.TIMEOUT_FACTOR) {
|
||||
throw new Exception("Uncommitted too slow");
|
||||
}
|
||||
|
||||
if (afterUncommit < beforeAlloc) {
|
||||
throw new Exception("Uncommitted too much");
|
||||
}
|
||||
|
||||
if (afterUncommit > beforeAlloc) {
|
||||
throw new Exception("Uncommitted too little");
|
||||
}
|
||||
|
||||
log("Success");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final boolean enabled = Boolean.parseBoolean(args[0]);
|
||||
final int iterations = Integer.parseInt(args[1]);
|
||||
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
System.out.println("Iteration " + i);
|
||||
test(enabled, smallObjectSize);
|
||||
test(enabled, mediumObjectSize);
|
||||
test(enabled, largeObjectSize);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
log("Iteration " + i);
|
||||
test(smallObjectSize);
|
||||
test(mediumObjectSize);
|
||||
test(largeObjectSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user