TestGCLogMessages.java revision 8157:655523dca4ea
1179065Sjb/*
2179065Sjb * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3211746Srpaulo * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4179065Sjb *
5179065Sjb * This code is free software; you can redistribute it and/or modify it
6211746Srpaulo * under the terms of the GNU General Public License version 2 only, as
7179065Sjb * published by the Free Software Foundation.
8179065Sjb *
9179065Sjb * This code is distributed in the hope that it will be useful, but WITHOUT
10179065Sjb * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11179065Sjb * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12179065Sjb * version 2 for more details (a copy is included in the LICENSE file that
13211690Simp * accompanied this code).
14179065Sjb *
15211746Srpaulo * You should have received a copy of the GNU General Public License version
16260670Sjhibbits * 2 along with this work; if not, write to the Free Software Foundation,
17260670Sjhibbits * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18260670Sjhibbits *
19179065Sjb * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20179065Sjb * or visit www.oracle.com if you need additional information or have any
21268734Spfg * questions.
22268734Spfg */
23268734Spfg
24253996Savg/*
25179065Sjb * @test TestGCLogMessages
26179065Sjb * @bug 8035406 8027295 8035398 8019342 8027959 8048179 8027962
27253996Savg * @summary Ensure that the PrintGCDetails output for a minor GC with G1
28253996Savg * includes the expected necessary messages.
29268734Spfg * @key gc
30253996Savg * @library /testlibrary
31 * @modules java.base/sun.misc
32 *          java.management
33 */
34
35import com.oracle.java.testlibrary.ProcessTools;
36import com.oracle.java.testlibrary.OutputAnalyzer;
37
38public class TestGCLogMessages {
39
40    private enum Level {
41        OFF, FINER, FINEST;
42        public boolean lessOrEqualTo(Level other) {
43            return this.compareTo(other) < 0;
44        }
45    }
46
47    private class LogMessageWithLevel {
48        String message;
49        Level level;
50
51        public LogMessageWithLevel(String message, Level level) {
52            this.message = message;
53            this.level = level;
54        }
55    };
56
57    private LogMessageWithLevel allLogMessages[] = new LogMessageWithLevel[] {
58        // Ext Root Scan
59        new LogMessageWithLevel("Thread Roots (ms)", Level.FINEST),
60        new LogMessageWithLevel("StringTable Roots (ms)", Level.FINEST),
61        new LogMessageWithLevel("Universe Roots (ms)", Level.FINEST),
62        new LogMessageWithLevel("JNI Handles Roots (ms)", Level.FINEST),
63        new LogMessageWithLevel("ObjectSynchronizer Roots (ms)", Level.FINEST),
64        new LogMessageWithLevel("FlatProfiler Roots", Level.FINEST),
65        new LogMessageWithLevel("Management Roots", Level.FINEST),
66        new LogMessageWithLevel("SystemDictionary Roots", Level.FINEST),
67        new LogMessageWithLevel("CLDG Roots", Level.FINEST),
68        new LogMessageWithLevel("JVMTI Roots", Level.FINEST),
69        new LogMessageWithLevel("SATB Filtering", Level.FINEST),
70        new LogMessageWithLevel("CM RefProcessor Roots", Level.FINEST),
71        new LogMessageWithLevel("Wait For Strong CLD", Level.FINEST),
72        new LogMessageWithLevel("Weak CLD Roots", Level.FINEST),
73        // Redirty Cards
74        new LogMessageWithLevel("Redirty Cards", Level.FINER),
75        new LogMessageWithLevel("Parallel Redirty", Level.FINEST),
76        new LogMessageWithLevel("Redirtied Cards", Level.FINEST),
77        // Misc Top-level
78        new LogMessageWithLevel("Code Root Purge", Level.FINER),
79        new LogMessageWithLevel("String Dedup Fixup", Level.FINER),
80        // Free CSet
81        new LogMessageWithLevel("Young Free CSet", Level.FINEST),
82        new LogMessageWithLevel("Non-Young Free CSet", Level.FINEST),
83        // Humongous Eager Reclaim
84        new LogMessageWithLevel("Humongous Reclaim", Level.FINER),
85        new LogMessageWithLevel("Humongous Register", Level.FINER),
86    };
87
88    void checkMessagesAtLevel(OutputAnalyzer output, LogMessageWithLevel messages[], Level level) throws Exception {
89        for (LogMessageWithLevel l : messages) {
90            if (level.lessOrEqualTo(l.level)) {
91                output.shouldNotContain(l.message);
92            } else {
93                output.shouldContain(l.message);
94            }
95        }
96    }
97
98    public static void main(String[] args) throws Exception {
99        new TestGCLogMessages().testNormalLogs();
100        new TestGCLogMessages().testWithToSpaceExhaustionLogs();
101    }
102
103    private void testNormalLogs() throws Exception {
104
105        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
106                                                                  "-Xmx10M",
107                                                                  GCTest.class.getName());
108
109        OutputAnalyzer output = new OutputAnalyzer(pb.start());
110        checkMessagesAtLevel(output, allLogMessages, Level.OFF);
111        output.shouldHaveExitValue(0);
112
113        pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
114                                                   "-XX:+UseStringDeduplication",
115                                                   "-Xmx10M",
116                                                   "-XX:+PrintGCDetails",
117                                                   GCTest.class.getName());
118
119        output = new OutputAnalyzer(pb.start());
120        checkMessagesAtLevel(output, allLogMessages, Level.FINER);
121
122        pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
123                                                   "-XX:+UseStringDeduplication",
124                                                   "-Xmx10M",
125                                                   "-XX:+PrintGCDetails",
126                                                   "-XX:+UnlockExperimentalVMOptions",
127                                                   "-XX:G1LogLevel=finest",
128                                                   GCTest.class.getName());
129
130        output = new OutputAnalyzer(pb.start());
131        checkMessagesAtLevel(output, allLogMessages, Level.FINEST);
132        output.shouldHaveExitValue(0);
133    }
134
135    LogMessageWithLevel exhFailureMessages[] = new LogMessageWithLevel[] {
136        new LogMessageWithLevel("Evacuation Failure", Level.FINER),
137        new LogMessageWithLevel("Recalculate Used", Level.FINEST),
138        new LogMessageWithLevel("Remove Self Forwards", Level.FINEST),
139        new LogMessageWithLevel("Restore RemSet", Level.FINEST),
140    };
141
142    private void testWithToSpaceExhaustionLogs() throws Exception {
143        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
144                                                                  "-Xmx32M",
145                                                                  "-Xmn16M",
146                                                                  "-XX:+PrintGCDetails",
147                                                                  GCTestWithToSpaceExhaustion.class.getName());
148
149        OutputAnalyzer output = new OutputAnalyzer(pb.start());
150        checkMessagesAtLevel(output, exhFailureMessages, Level.FINER);
151        output.shouldHaveExitValue(0);
152
153        pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
154                                                   "-Xmx32M",
155                                                   "-Xmn16M",
156                                                   "-XX:+PrintGCDetails",
157                                                   "-XX:+UnlockExperimentalVMOptions",
158                                                   "-XX:G1LogLevel=finest",
159                                                   GCTestWithToSpaceExhaustion.class.getName());
160
161        output = new OutputAnalyzer(pb.start());
162        checkMessagesAtLevel(output, exhFailureMessages, Level.FINEST);
163        output.shouldHaveExitValue(0);
164    }
165
166    static class GCTest {
167        private static byte[] garbage;
168        public static void main(String [] args) {
169            System.out.println("Creating garbage");
170            // create 128MB of garbage. This should result in at least one GC
171            for (int i = 0; i < 1024; i++) {
172                garbage = new byte[128 * 1024];
173            }
174            System.out.println("Done");
175        }
176    }
177
178    static class GCTestWithToSpaceExhaustion {
179        private static byte[] garbage;
180        private static byte[] largeObject;
181        public static void main(String [] args) {
182            largeObject = new byte[16*1024*1024];
183            System.out.println("Creating garbage");
184            // create 128MB of garbage. This should result in at least one GC,
185            // some of them with to-space exhaustion.
186            for (int i = 0; i < 1024; i++) {
187                garbage = new byte[128 * 1024];
188            }
189            System.out.println("Done");
190        }
191    }
192}
193
194