1 /*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
43 import jdk.test.lib.HeapRegionUsageTool;
44 import jdk.test.lib.OutputAnalyzer;
45 import jdk.test.lib.ProcessTools;
46 import jdk.test.lib.Utils;
47 import sun.hotspot.WhiteBox;
48
49 public class TestNewSizeFlags {
50
51 public static final long M = 1024 * 1024;
52
53 public static void main(String args[]) throws Exception {
54 LinkedList<String> options = new LinkedList<>(
55 Arrays.asList(Utils.getFilteredTestJavaOpts("(-Xm[nsx][^ ]+)|"
56 + "(-XX:(Max)?((New)|"
57 + "(Heap))((Size)|"
58 + "(Ratio))=[^ ]+)"))
59 );
60
61 // Test NewSize and MaxNewSize
62 testNewSizeFlags(20 * M, 10 * M, 30 * M, 40 * M, options, false);
63 testNewSizeFlags(10 * M, 20 * M, 30 * M, 40 * M, options, false);
64 testNewSizeFlags(-1, 20 * M, 30 * M, 40 * M, options, false);
65 testNewSizeFlags(10 * M, -1, 30 * M, 40 * M, options, false);
66 testNewSizeFlags(20 * M, 20 * M, 30 * M, 40 * M, options, false);
67 testNewSizeFlags(20 * M, 30 * M, 40 * M, 50 * M, options, false);
68 testNewSizeFlags(30 * M, 100 * M, 150 * M, 200 * M, options, false);
69 testNewSizeFlags(0, -1, 30 * M, 40 * M, options, false);
70
71 // Test -Xmn
72 testXmnFlags(0, 30 * M, 40 * M, options, true);
73 testXmnFlags(20 * M, 30 * M, 40 * M, options, false);
74 testXmnFlags(50 * M, 70 * M, 100 * M, options, false);
75 }
76
77 /**
78 * Verify that NewSize and MaxNewSize flags affect young gen size.
79 *
80 * @param newSize value of NewSize option, omitted if negative
81 * @param maxNewSize value of MaxNewSize option, omitted if negative
82 * @param heapSize value of HeapSize option
83 * @param maxHeapSize value of MaxHeapSize option
84 * @param options additional options for JVM
85 * @param failureExpected true if JVM should fail with passed heap size options
86 */
87 public static void testNewSizeFlags(long newSize, long maxNewSize,
88 long heapSize, long maxHeapSize,
89 LinkedList<String> options,
90 boolean failureExpected) throws Exception {
91 testVMOptions(newSize, maxNewSize,
92 heapSize, maxHeapSize,
93 newSize, (maxNewSize >= 0 ? Math.max(maxNewSize, newSize) : maxNewSize),
94 options, failureExpected);
95 }
96
97 /**
98 * Verify that -Xmn flag affect young gen size.
99 *
100 * @param mnValue value of -Xmn option
101 * @param heapSize value of HeapSize option
102 * @param maxHeapSize value of MaxHeapSize option
103 * @param options additional options for JVM
104 * @param failureExpected true if JVM should fail with passed heap size options
105 */
106 public static void testXmnFlags(long mnValue,
107 long heapSize, long maxHeapSize,
108 LinkedList<String> options,
109 boolean failureExpected) throws Exception {
110 LinkedList<String> newOptions = new LinkedList<>(options);
111 newOptions.add("-Xmn" + mnValue);
112 testVMOptions(-1, -1,
113 heapSize, maxHeapSize,
142 }
143 }
144
145 private static OutputAnalyzer startVM(LinkedList<String> options,
146 long newSize, long maxNewSize,
147 long heapSize, long maxHeapSize,
148 long expectedNewSize, long expectedMaxNewSize) throws Exception, IOException {
149 LinkedList<String> vmOptions = new LinkedList<>(options);
150 Collections.addAll(vmOptions,
151 "-Xbootclasspath/a:.",
152 "-XX:+UnlockDiagnosticVMOptions",
153 "-XX:+WhiteBoxAPI",
154 (newSize >= 0 ? "-XX:NewSize=" + newSize : ""),
155 (maxNewSize >= 0 ? "-XX:MaxNewSize=" + maxNewSize : ""),
156 "-Xmx" + maxHeapSize,
157 "-Xms" + heapSize,
158 "-XX:GCLockerEdenExpansionPercent=0",
159 "-XX:-UseLargePages",
160 NewSizeVerifier.class.getName(),
161 Long.toString(expectedNewSize),
162 Long.toString(expectedMaxNewSize)
163 );
164 vmOptions.removeIf(String::isEmpty);
165 ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
166 OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
167 return analyzer;
168 }
169
170 /**
171 * NewSizeVerifier checks that initial young gen size is equal to expected
172 * regardful to alignment and that young gen size will not be greater than
173 * expected max size.
174 * In order to verify that young gen size will not be greater then expected
175 * max size, NewSizeVerifier do some object allocation to force garbage
176 * collection and heap expansion.
177 */
178 public static class NewSizeVerifier {
179
180 static WhiteBox wb = WhiteBox.getWhiteBox();
181
182 public static final int ARRAY_LENGTH = 100;
183 public static final int CHUNK_SIZE = 1024;
184 public static final int MAX_ITERATIONS = 10;
185 public static byte garbage[][] = new byte[ARRAY_LENGTH][];
186
187 public static void main(String args[]) throws Exception {
188 if (args.length != 2) {
189 throw new IllegalArgumentException("Expected 2 args: <expectedNewSize> <expectedMaxNewSize>");
190 }
191 final long newSize = Long.valueOf(args[0]);
192 final long maxNewSize = Long.valueOf(args[1]);
193
194 // verify initial size
195 verifyNewSize(newSize, maxNewSize);
196
197 // force GC and verify that size is still correct
198 AllocationHelper allocator = new AllocationHelper(MAX_ITERATIONS, ARRAY_LENGTH, CHUNK_SIZE, () -> (verifyNewSize(newSize, maxNewSize)));
199 allocator.allocateMemoryAndVerifyNoOOME();
200 }
201
202 /**
203 * Verify that actual young gen size conforms NewSize and MaxNewSize values.
204 */
205 public static Void verifyNewSize(long newSize, long maxNewSize) {
206 long alignedNewSize = alignNewSize(newSize);
207 long alignedMaxNewSize = alignNewSize(maxNewSize);
208
209 MemoryUsage youngGenUsage = getYoungGenUsage();
210
211 if (newSize != -1) {
212 if (youngGenUsage.getInit() < alignedNewSize) {
213 throw new RuntimeException("initial new size < NewSize value: "
214 + youngGenUsage.getInit() + " < " + alignedNewSize);
215 }
216
217 if (youngGenUsage.getCommitted() < alignedNewSize) {
218 throw new RuntimeException("actual new size < NewSize value: "
219 + youngGenUsage.getCommitted() + " < " + alignedNewSize);
220 }
221
222 // for G1 max new size == committed new size
223 if (GCTypes.YoungGCType.getYoungGCType() != GCTypes.YoungGCType.G1
224 && youngGenUsage.getMax() < alignedNewSize) {
225 throw new RuntimeException("max new size < NewSize value: "
226 + youngGenUsage.getMax() + " < " + alignedNewSize);
227 }
228 }
229
230 if (maxNewSize != -1) {
231 if (youngGenUsage.getInit() > alignedMaxNewSize) {
232 throw new RuntimeException("initial new size > MaxNewSize value: "
233 + youngGenUsage.getInit() + " > " + alignedMaxNewSize);
234 }
235
236 if (youngGenUsage.getCommitted() > alignedMaxNewSize) {
237 throw new RuntimeException("actual new size > MaxNewSize value: "
238 + youngGenUsage.getCommitted() + " > " + alignedMaxNewSize);
239 }
240
241 if (GCTypes.YoungGCType.getYoungGCType() != GCTypes.YoungGCType.G1
242 && youngGenUsage.getMax() != alignedMaxNewSize) {
243 throw new RuntimeException("max new size != MaxNewSize value: "
244 + youngGenUsage.getMax() + " != " + alignedMaxNewSize);
245 }
246 }
247 return null;
248 }
249
250 /**
251 * Get young gen memory usage.
252 *
253 * For G1 it is EdenUsage + SurvivorUsage,
254 * for other GCs it is EdenUsage + 2 * SurvivorUsage.
255 * For G1 max value is just LONG_MAX.
256 * For all GCs used value is 0.
257 */
258 private static MemoryUsage getYoungGenUsage() {
259 if (GCTypes.YoungGCType.getYoungGCType() == GCTypes.YoungGCType.G1) {
260 return new MemoryUsage(HeapRegionUsageTool.getEdenUsage().getInit()
261 + HeapRegionUsageTool.getSurvivorUsage().getInit(),
262 0,
263 HeapRegionUsageTool.getEdenUsage().getCommitted()
264 + HeapRegionUsageTool.getSurvivorUsage().getCommitted(),
265 Long.MAX_VALUE);
266 } else {
267 return new MemoryUsage(HeapRegionUsageTool.getEdenUsage().getInit()
268 + HeapRegionUsageTool.getSurvivorUsage().getInit() * 2,
269 0,
270 HeapRegionUsageTool.getEdenUsage().getCommitted()
271 + HeapRegionUsageTool.getSurvivorUsage().getCommitted() * 2,
272 HeapRegionUsageTool.getEdenUsage().getMax()
273 + HeapRegionUsageTool.getSurvivorUsage().getMax() * 2);
274 }
275 }
276
277 /**
278 * Align value regardful to used young GC.
279 */
280 public static long alignNewSize(long value) {
281 switch (GCTypes.YoungGCType.getYoungGCType()) {
282 case DefNew:
283 case ParNew:
284 return HeapRegionUsageTool.alignDown(value, wb.getHeapSpaceAlignment());
285 case PSNew:
286 return HeapRegionUsageTool.alignUp(HeapRegionUsageTool.alignDown(value,
287 wb.getHeapSpaceAlignment()),
288 wb.psVirtualSpaceAlignment());
289 case G1:
290 return HeapRegionUsageTool.alignUp(value, wb.g1RegionSize());
291 default:
292 throw new RuntimeException("Unexpected young GC type");
293 }
294 }
295 }
296 }
|
1 /*
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
43 import jdk.test.lib.HeapRegionUsageTool;
44 import jdk.test.lib.OutputAnalyzer;
45 import jdk.test.lib.ProcessTools;
46 import jdk.test.lib.Utils;
47 import sun.hotspot.WhiteBox;
48
49 public class TestNewSizeFlags {
50
51 public static final long M = 1024 * 1024;
52
53 public static void main(String args[]) throws Exception {
54 LinkedList<String> options = new LinkedList<>(
55 Arrays.asList(Utils.getFilteredTestJavaOpts("(-Xm[nsx][^ ]+)|"
56 + "(-XX:(Max)?((New)|"
57 + "(Heap))((Size)|"
58 + "(Ratio))=[^ ]+)"))
59 );
60
61 // Test NewSize and MaxNewSize
62 testNewSizeFlags(20 * M, 10 * M, 30 * M, 40 * M, options, false);
63 testNewSizeFlags(10 * M, 20 * M, 30 * M, 80 * M, options, false);
64 testNewSizeFlags(-1, 20 * M, 30 * M, 40 * M, options, false);
65 testNewSizeFlags(10 * M, -1, 30 * M, 40 * M, options, false);
66 testNewSizeFlags(20 * M, 20 * M, 30 * M, 40 * M, options, false);
67 testNewSizeFlags(20 * M, 30 * M, 40 * M, 50 * M, options, false);
68 testNewSizeFlags(30 * M, 100 * M, 150 * M, 200 * M, options, false);
69 testNewSizeFlags(20 * M, 30 * M, 128 * M, 128 * M, options, false);
70
71 // Test -Xmn
72 testXmnFlags(0, 30 * M, 40 * M, options, true);
73 testXmnFlags(20 * M, 30 * M, 40 * M, options, false);
74 testXmnFlags(50 * M, 70 * M, 100 * M, options, false);
75 }
76
77 /**
78 * Verify that NewSize and MaxNewSize flags affect young gen size.
79 *
80 * @param newSize value of NewSize option, omitted if negative
81 * @param maxNewSize value of MaxNewSize option, omitted if negative
82 * @param heapSize value of HeapSize option
83 * @param maxHeapSize value of MaxHeapSize option
84 * @param options additional options for JVM
85 * @param failureExpected true if JVM should fail with passed heap size options
86 */
87 public static void testNewSizeFlags(long newSize, long maxNewSize,
88 long heapSize, long maxHeapSize,
89 LinkedList<String> options,
90 boolean failureExpected) throws Exception {
91 long expectedNewSize = newSize;
92 long expectedMaxNewSize = (maxNewSize >= 0 ? Math.max(maxNewSize, newSize) : maxNewSize);
93 testVMOptions(newSize, maxNewSize,
94 heapSize, maxHeapSize,
95 expectedNewSize, expectedMaxNewSize,
96 options, failureExpected);
97 }
98
99 /**
100 * Verify that -Xmn flag affect young gen size.
101 *
102 * @param mnValue value of -Xmn option
103 * @param heapSize value of HeapSize option
104 * @param maxHeapSize value of MaxHeapSize option
105 * @param options additional options for JVM
106 * @param failureExpected true if JVM should fail with passed heap size options
107 */
108 public static void testXmnFlags(long mnValue,
109 long heapSize, long maxHeapSize,
110 LinkedList<String> options,
111 boolean failureExpected) throws Exception {
112 LinkedList<String> newOptions = new LinkedList<>(options);
113 newOptions.add("-Xmn" + mnValue);
114 testVMOptions(-1, -1,
115 heapSize, maxHeapSize,
144 }
145 }
146
147 private static OutputAnalyzer startVM(LinkedList<String> options,
148 long newSize, long maxNewSize,
149 long heapSize, long maxHeapSize,
150 long expectedNewSize, long expectedMaxNewSize) throws Exception, IOException {
151 LinkedList<String> vmOptions = new LinkedList<>(options);
152 Collections.addAll(vmOptions,
153 "-Xbootclasspath/a:.",
154 "-XX:+UnlockDiagnosticVMOptions",
155 "-XX:+WhiteBoxAPI",
156 (newSize >= 0 ? "-XX:NewSize=" + newSize : ""),
157 (maxNewSize >= 0 ? "-XX:MaxNewSize=" + maxNewSize : ""),
158 "-Xmx" + maxHeapSize,
159 "-Xms" + heapSize,
160 "-XX:GCLockerEdenExpansionPercent=0",
161 "-XX:-UseLargePages",
162 NewSizeVerifier.class.getName(),
163 Long.toString(expectedNewSize),
164 Long.toString(expectedMaxNewSize),
165 Long.toString(heapSize),
166 Long.toString(maxHeapSize)
167 );
168 vmOptions.removeIf(String::isEmpty);
169 ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
170 OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
171 return analyzer;
172 }
173
174 /**
175 * NewSizeVerifier checks that initial young gen size is equal to expected
176 * regardful to alignment and that young gen size will not be greater than
177 * expected max size.
178 * In order to verify that young gen size will not be greater then expected
179 * max size, NewSizeVerifier do some object allocation to force garbage
180 * collection and heap expansion.
181 */
182 public static class NewSizeVerifier {
183
184 private static final WhiteBox WB = WhiteBox.getWhiteBox();
185 private static final GCTypes.YoungGCType YOUNG_GC_TYPE = GCTypes.YoungGCType.getYoungGCType();
186 private static final long HEAP_SPACE_ALIGNMENT = WB.getHeapSpaceAlignment();
187 private static final long HEAP_ALIGNMENT = WB.getHeapAlignment();
188 private static final long PS_VIRTUAL_SPACE_ALIGNMENT =
189 (YOUNG_GC_TYPE == GCTypes.YoungGCType.PSNew) ? WB.psVirtualSpaceAlignment() : 0;
190
191 public static final int ARRAY_LENGTH = 100;
192 public static final int CHUNK_SIZE = 1024;
193 public static final int MAX_ITERATIONS = 10;
194 public static byte garbage[][] = new byte[ARRAY_LENGTH][];
195
196 public static void main(String args[]) throws Exception {
197 if (args.length != 4) {
198 throw new IllegalArgumentException("Expected 4 args: <expectedNewSize> <expectedMaxNewSize> <initialHeapSize> <maxHeapSize>");
199 }
200 final long newSize = Long.valueOf(args[0]);
201 final long maxNewSize = Long.valueOf(args[1]);
202 final long initialHeapSize = Long.valueOf(args[2]);
203 final long maxHeapSize = Long.valueOf(args[3]);
204
205 // verify initial size
206 verifyNewSize(newSize, maxNewSize, initialHeapSize, maxHeapSize);
207
208 // force GC and verify that size is still correct
209 AllocationHelper allocator = new AllocationHelper(MAX_ITERATIONS, ARRAY_LENGTH, CHUNK_SIZE, () -> (verifyNewSize(newSize, maxNewSize, initialHeapSize, maxHeapSize)));
210 allocator.allocateMemoryAndVerifyNoOOME();
211 }
212
213 /**
214 * Verify that actual young gen size conforms NewSize and MaxNewSize values.
215 */
216 public static Void verifyNewSize(long newSize, long maxNewSize,
217 long initialHeapSize, long maxHeapSize) {
218 long alignedNewSize = alignGenSize(newSize);
219 long alignedMaxNewSize = alignGenSize(maxNewSize);
220 long alignedXms = alignHeapSize(initialHeapSize);
221 long alignedXmx = alignHeapSize(maxHeapSize);
222
223 MemoryUsage youngGenUsage = getYoungGenUsage();
224 long initSize = youngGenUsage.getInit();
225 long commitedSize = youngGenUsage.getCommitted();
226 long maxSize = youngGenUsage.getMax();
227
228 if (newSize != -1) {
229 if (initSize < alignedNewSize) {
230 throw new RuntimeException("initial new size < NewSize value: "
231 + initSize + " < " + alignedNewSize);
232 }
233
234 if (commitedSize < alignedNewSize) {
235 throw new RuntimeException("actual new size < NewSize value: "
236 + commitedSize + " < " + alignedNewSize);
237 }
238
239 // for G1 max new size == committed new size
240 if (YOUNG_GC_TYPE != GCTypes.YoungGCType.G1
241 && maxSize < alignedNewSize) {
242 throw new RuntimeException("max new size < NewSize value: "
243 + maxSize + " < " + alignedNewSize);
244 }
245 }
246
247 if (maxNewSize != -1) {
248 if (initSize > alignedMaxNewSize) {
249 throw new RuntimeException("initial new size > MaxNewSize value: "
250 + initSize + " > " + alignedMaxNewSize);
251 }
252
253 if (commitedSize > alignedMaxNewSize) {
254 throw new RuntimeException("actual new size > MaxNewSize value: "
255 + commitedSize + " > " + alignedMaxNewSize);
256 }
257
258 if (alignedXms != alignedXmx) {
259 if (YOUNG_GC_TYPE != GCTypes.YoungGCType.G1
260 && maxSize != alignedMaxNewSize) {
261 throw new RuntimeException("max new size != MaxNewSize value: "
262 + maxSize + " != " + alignedMaxNewSize);
263 }
264 } else {
265 if (YOUNG_GC_TYPE != GCTypes.YoungGCType.G1
266 && maxSize != alignedNewSize) {
267 throw new RuntimeException("max new size != NewSize for case InitialHeapSize == MaxHeapSize value: "
268 + maxSize + " != " + alignedNewSize + " HeapSize == " + alignedXms);
269 }
270 }
271 }
272 return null;
273 }
274
275 /**
276 * Get young gen memory usage.
277 *
278 * For G1 it is EdenUsage + SurvivorUsage,
279 * for other GCs it is EdenUsage + 2 * SurvivorUsage.
280 * For G1 max value is just LONG_MAX.
281 * For all GCs used value is 0.
282 */
283 private static MemoryUsage getYoungGenUsage() {
284 MemoryUsage edenUsage = HeapRegionUsageTool.getEdenUsage();
285 MemoryUsage survivorUsage = HeapRegionUsageTool.getSurvivorUsage();
286 long edenUsageInit = edenUsage.getInit();
287 long edenUsageCommited = edenUsage.getCommitted();
288 long survivorUsageInit = survivorUsage.getInit();
289 long survivorUsageCommited = survivorUsage.getCommitted();
290
291 if (YOUNG_GC_TYPE == GCTypes.YoungGCType.G1) {
292 return new MemoryUsage(edenUsageInit + survivorUsageInit, 0,
293 edenUsageCommited + survivorUsageCommited, Long.MAX_VALUE);
294 } else {
295 return new MemoryUsage(edenUsageInit + survivorUsageInit * 2, 0,
296 edenUsageCommited + survivorUsageCommited * 2,
297 edenUsage.getMax() + survivorUsage.getMax() * 2);
298 }
299 }
300
301 /**
302 * Align generation size regardful to used young GC.
303 */
304 public static long alignGenSize(long value) {
305 switch (YOUNG_GC_TYPE) {
306 case DefNew:
307 case ParNew:
308 return HeapRegionUsageTool.alignDown(value, HEAP_SPACE_ALIGNMENT);
309 case PSNew:
310 return HeapRegionUsageTool.alignUp(HeapRegionUsageTool.alignDown(value,
311 HEAP_SPACE_ALIGNMENT),
312 PS_VIRTUAL_SPACE_ALIGNMENT);
313 case G1:
314 return HeapRegionUsageTool.alignUp(value, WB.g1RegionSize());
315 default:
316 throw new RuntimeException("Unexpected young GC type");
317 }
318 }
319
320 /**
321 * Align heap size.
322 */
323 public static long alignHeapSize(long value){
324 return HeapRegionUsageTool.alignUp(value,HEAP_ALIGNMENT);
325 }
326 }
327 }
|