2014-03-17 09:12:21 +00:00
|
|
|
/*
|
2016-02-26 12:02:30 +00:00
|
|
|
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
2014-03-17 09:12:21 +00:00
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2014-05-11 23:35:43 +00:00
|
|
|
* @test TestGCLogMessages
|
2016-10-24 14:10:30 +00:00
|
|
|
* @bug 8035406 8027295 8035398 8019342 8027959 8048179 8027962 8069330 8076463 8150630 8160055
|
2015-12-10 13:57:55 +00:00
|
|
|
* @summary Ensure the output for a minor GC with G1
|
2014-03-17 09:12:21 +00:00
|
|
|
* includes the expected necessary messages.
|
|
|
|
* @key gc
|
2016-08-29 19:04:48 +00:00
|
|
|
* @requires vm.gc.G1
|
2016-08-19 14:06:30 +00:00
|
|
|
* @library /test/lib
|
2016-04-09 22:03:39 +00:00
|
|
|
* @modules java.base/jdk.internal.misc
|
2015-03-26 15:36:56 +00:00
|
|
|
* java.management
|
2016-10-24 14:10:30 +00:00
|
|
|
* @build sun.hotspot.WhiteBox
|
|
|
|
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
|
|
|
* @run main TestGCLogMessages
|
2014-03-17 09:12:21 +00:00
|
|
|
*/
|
|
|
|
|
2016-08-19 14:06:30 +00:00
|
|
|
import jdk.test.lib.process.OutputAnalyzer;
|
|
|
|
import jdk.test.lib.process.ProcessTools;
|
2014-03-17 09:12:21 +00:00
|
|
|
|
|
|
|
public class TestGCLogMessages {
|
2015-03-19 14:25:54 +00:00
|
|
|
|
|
|
|
private enum Level {
|
2016-02-29 12:06:03 +00:00
|
|
|
OFF(""),
|
|
|
|
INFO("info"),
|
|
|
|
DEBUG("debug"),
|
|
|
|
TRACE("trace");
|
|
|
|
|
|
|
|
private String logName;
|
|
|
|
|
|
|
|
Level(String logName) {
|
|
|
|
this.logName = logName;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean lessThan(Level other) {
|
2015-03-19 14:25:54 +00:00
|
|
|
return this.compareTo(other) < 0;
|
|
|
|
}
|
2016-02-29 12:06:03 +00:00
|
|
|
|
|
|
|
public String toString() {
|
|
|
|
return logName;
|
|
|
|
}
|
2014-03-17 09:12:21 +00:00
|
|
|
}
|
2015-03-19 14:25:54 +00:00
|
|
|
|
|
|
|
private class LogMessageWithLevel {
|
|
|
|
String message;
|
|
|
|
Level level;
|
|
|
|
|
|
|
|
public LogMessageWithLevel(String message, Level level) {
|
|
|
|
this.message = message;
|
|
|
|
this.level = level;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
private LogMessageWithLevel allLogMessages[] = new LogMessageWithLevel[] {
|
2015-10-13 12:49:13 +00:00
|
|
|
// Update RS
|
2016-02-29 12:06:03 +00:00
|
|
|
new LogMessageWithLevel("Scan HCC", Level.TRACE),
|
2015-03-19 14:25:54 +00:00
|
|
|
// Ext Root Scan
|
2016-02-29 12:06:03 +00:00
|
|
|
new LogMessageWithLevel("Thread Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("StringTable Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("Universe Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("JNI Handles Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("ObjectSynchronizer Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("FlatProfiler Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("Management Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("SystemDictionary Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("CLDG Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("JVMTI Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("SATB Filtering", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("CM RefProcessor Roots", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("Wait For Strong CLD", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("Weak CLD Roots", Level.TRACE),
|
2015-03-19 14:25:54 +00:00
|
|
|
// Redirty Cards
|
2015-12-10 13:57:55 +00:00
|
|
|
new LogMessageWithLevel("Redirty Cards", Level.DEBUG),
|
2016-02-29 12:06:03 +00:00
|
|
|
new LogMessageWithLevel("Parallel Redirty", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("Redirtied Cards", Level.TRACE),
|
2015-03-19 14:25:54 +00:00
|
|
|
// Misc Top-level
|
2016-02-29 12:06:03 +00:00
|
|
|
new LogMessageWithLevel("Code Roots Purge", Level.DEBUG),
|
|
|
|
new LogMessageWithLevel("String Dedup Fixup", Level.INFO),
|
|
|
|
new LogMessageWithLevel("Expand Heap After Collection", Level.INFO),
|
2015-03-19 14:25:54 +00:00
|
|
|
// Free CSet
|
2016-07-19 08:31:41 +00:00
|
|
|
new LogMessageWithLevel("Free Collection Set", Level.INFO),
|
|
|
|
new LogMessageWithLevel("Free Collection Set Serial", Level.DEBUG),
|
2016-02-29 12:06:03 +00:00
|
|
|
new LogMessageWithLevel("Young Free Collection Set", Level.DEBUG),
|
|
|
|
new LogMessageWithLevel("Non-Young Free Collection Set", Level.DEBUG),
|
2015-03-19 14:25:54 +00:00
|
|
|
// Humongous Eager Reclaim
|
2015-12-10 13:57:55 +00:00
|
|
|
new LogMessageWithLevel("Humongous Reclaim", Level.DEBUG),
|
|
|
|
new LogMessageWithLevel("Humongous Register", Level.DEBUG),
|
2016-02-26 12:02:30 +00:00
|
|
|
// Preserve CM Referents
|
|
|
|
new LogMessageWithLevel("Preserve CM Refs", Level.DEBUG),
|
2016-02-26 12:02:30 +00:00
|
|
|
// Merge PSS
|
2016-02-29 12:06:03 +00:00
|
|
|
new LogMessageWithLevel("Merge Per-Thread State", Level.INFO),
|
2015-03-19 14:25:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void checkMessagesAtLevel(OutputAnalyzer output, LogMessageWithLevel messages[], Level level) throws Exception {
|
|
|
|
for (LogMessageWithLevel l : messages) {
|
2016-02-29 12:06:03 +00:00
|
|
|
if (level.lessThan(l.level)) {
|
2015-03-19 14:25:54 +00:00
|
|
|
output.shouldNotContain(l.message);
|
|
|
|
} else {
|
2016-02-29 12:06:03 +00:00
|
|
|
output.shouldMatch("\\[" + l.level + ".*" + l.message);
|
2015-03-19 14:25:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
|
|
new TestGCLogMessages().testNormalLogs();
|
|
|
|
new TestGCLogMessages().testWithToSpaceExhaustionLogs();
|
2016-10-24 14:10:30 +00:00
|
|
|
new TestGCLogMessages().testWithInitialMark();
|
2015-03-19 14:25:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void testNormalLogs() throws Exception {
|
|
|
|
|
|
|
|
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
|
|
|
|
"-Xmx10M",
|
|
|
|
GCTest.class.getName());
|
|
|
|
|
|
|
|
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
|
|
|
checkMessagesAtLevel(output, allLogMessages, Level.OFF);
|
|
|
|
output.shouldHaveExitValue(0);
|
|
|
|
|
|
|
|
pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
|
|
|
|
"-XX:+UseStringDeduplication",
|
|
|
|
"-Xmx10M",
|
2015-12-10 13:57:55 +00:00
|
|
|
"-Xlog:gc+phases=debug",
|
2015-03-19 14:25:54 +00:00
|
|
|
GCTest.class.getName());
|
|
|
|
|
|
|
|
output = new OutputAnalyzer(pb.start());
|
2015-12-10 13:57:55 +00:00
|
|
|
checkMessagesAtLevel(output, allLogMessages, Level.DEBUG);
|
2015-03-19 14:25:54 +00:00
|
|
|
|
|
|
|
pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
|
|
|
|
"-XX:+UseStringDeduplication",
|
|
|
|
"-Xmx10M",
|
2015-12-10 13:57:55 +00:00
|
|
|
"-Xlog:gc+phases=trace",
|
2015-03-19 14:25:54 +00:00
|
|
|
GCTest.class.getName());
|
|
|
|
|
|
|
|
output = new OutputAnalyzer(pb.start());
|
2015-12-10 13:57:55 +00:00
|
|
|
checkMessagesAtLevel(output, allLogMessages, Level.TRACE);
|
2015-03-19 14:25:54 +00:00
|
|
|
output.shouldHaveExitValue(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
LogMessageWithLevel exhFailureMessages[] = new LogMessageWithLevel[] {
|
2015-12-10 13:57:55 +00:00
|
|
|
new LogMessageWithLevel("Evacuation Failure", Level.DEBUG),
|
|
|
|
new LogMessageWithLevel("Recalculate Used", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("Remove Self Forwards", Level.TRACE),
|
|
|
|
new LogMessageWithLevel("Restore RemSet", Level.TRACE),
|
2015-03-19 14:25:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
private void testWithToSpaceExhaustionLogs() throws Exception {
|
|
|
|
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
|
|
|
|
"-Xmx32M",
|
|
|
|
"-Xmn16M",
|
2015-12-10 13:57:55 +00:00
|
|
|
"-Xlog:gc+phases=debug",
|
2015-03-19 14:25:54 +00:00
|
|
|
GCTestWithToSpaceExhaustion.class.getName());
|
|
|
|
|
|
|
|
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
2015-12-10 13:57:55 +00:00
|
|
|
checkMessagesAtLevel(output, exhFailureMessages, Level.DEBUG);
|
2015-03-19 14:25:54 +00:00
|
|
|
output.shouldHaveExitValue(0);
|
|
|
|
|
|
|
|
pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
|
|
|
|
"-Xmx32M",
|
|
|
|
"-Xmn16M",
|
2015-12-10 13:57:55 +00:00
|
|
|
"-Xlog:gc+phases=trace",
|
2015-03-19 14:25:54 +00:00
|
|
|
GCTestWithToSpaceExhaustion.class.getName());
|
|
|
|
|
|
|
|
output = new OutputAnalyzer(pb.start());
|
2015-12-10 13:57:55 +00:00
|
|
|
checkMessagesAtLevel(output, exhFailureMessages, Level.TRACE);
|
2015-03-19 14:25:54 +00:00
|
|
|
output.shouldHaveExitValue(0);
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:10:30 +00:00
|
|
|
private void testWithInitialMark() throws Exception {
|
|
|
|
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
|
|
|
|
"-Xmx10M",
|
|
|
|
"-Xbootclasspath/a:.",
|
|
|
|
"-Xlog:gc*=debug",
|
|
|
|
"-XX:+UnlockDiagnosticVMOptions",
|
|
|
|
"-XX:+WhiteBoxAPI",
|
|
|
|
GCTestWithInitialMark.class.getName());
|
|
|
|
|
|
|
|
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
|
|
|
output.shouldContain("Clear Claimed Marks");
|
|
|
|
output.shouldHaveExitValue(0);
|
|
|
|
}
|
|
|
|
|
2015-03-19 14:25:54 +00:00
|
|
|
static class GCTest {
|
|
|
|
private static byte[] garbage;
|
|
|
|
public static void main(String [] args) {
|
|
|
|
System.out.println("Creating garbage");
|
|
|
|
// create 128MB of garbage. This should result in at least one GC
|
|
|
|
for (int i = 0; i < 1024; i++) {
|
|
|
|
garbage = new byte[128 * 1024];
|
|
|
|
}
|
|
|
|
System.out.println("Done");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static class GCTestWithToSpaceExhaustion {
|
|
|
|
private static byte[] garbage;
|
|
|
|
private static byte[] largeObject;
|
|
|
|
public static void main(String [] args) {
|
|
|
|
largeObject = new byte[16*1024*1024];
|
|
|
|
System.out.println("Creating garbage");
|
|
|
|
// create 128MB of garbage. This should result in at least one GC,
|
|
|
|
// some of them with to-space exhaustion.
|
|
|
|
for (int i = 0; i < 1024; i++) {
|
|
|
|
garbage = new byte[128 * 1024];
|
|
|
|
}
|
|
|
|
System.out.println("Done");
|
|
|
|
}
|
2014-03-17 09:13:42 +00:00
|
|
|
}
|
2016-10-24 14:10:30 +00:00
|
|
|
|
|
|
|
static class GCTestWithInitialMark {
|
|
|
|
public static void main(String [] args) {
|
|
|
|
sun.hotspot.WhiteBox WB = sun.hotspot.WhiteBox.getWhiteBox();
|
|
|
|
WB.g1StartConcMarkCycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-17 09:12:21 +00:00
|
|
|
}
|
2015-03-19 14:25:54 +00:00
|
|
|
|