1 /*
2  * Copyright (c) 2015, 2019, 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  */
23 
24 package gc.arguments;
25 
26 /*
27  * @test TestNewSizeThreadIncrease
28  * @key gc
29  * @bug 8144527
30  * @summary Tests argument processing for NewSizeThreadIncrease
31  * @library /test/lib
32  * @library /
33  * @requires vm.gc.Serial
34  * @modules java.base/jdk.internal.misc
35  *          java.management
36  * @run main gc.arguments.TestNewSizeThreadIncrease
37  */
38 
39 
40 import jdk.test.lib.Platform;
41 import jdk.test.lib.process.OutputAnalyzer;
42 import jdk.test.lib.process.ProcessTools;
43 
44 
45 // Range of NewSizeThreadIncrease is 0 ~ max_uintx.
46 // Total of 5 threads will be created (1 GCTest thread and 4 TestThread).
47 public class TestNewSizeThreadIncrease {
48   static final String VALID_VALUE = "2097152"; // 2MB
49 
50   // This value will make an overflow of 'thread count * NewSizeThreadIncrease' at DefNewGeneration::compute_new_size().
51   // = (max_uintx / 5) + 1, = (18446744073709551615 / 5) + 1
52   static String INVALID_VALUE_1 = "3689348814741910324";
53 
54   // This string is contained when compute_new_size() expands or shrinks.
55   static final String LOG_NEWSIZE_CHANGED = "New generation size ";
56 
main(String[] args)57   public static void main(String[] args) throws Exception {
58     if (Platform.is32bit()) {
59       // (max_uintx / 5) + 1, 4294967295/5 + 1
60       INVALID_VALUE_1 = "858993460";
61     }
62 
63     // New size will be applied as NewSizeThreadIncrease is small enough to expand.
64     runNewSizeThreadIncreaseTest(VALID_VALUE, true);
65 
66     // New size will be ignored as 'thread count * NewSizeThreadIncrease' overflows.
67     runNewSizeThreadIncreaseTest(INVALID_VALUE_1, false);
68   }
69 
runNewSizeThreadIncreaseTest(String expectedValue, boolean isNewsizeChanged)70   static void runNewSizeThreadIncreaseTest(String expectedValue, boolean isNewsizeChanged) throws Exception {
71     ProcessBuilder pb = GCArguments.createJavaProcessBuilder("-XX:+UseSerialGC",
72                                                              "-Xms96M",
73                                                              "-Xmx128M",
74                                                              "-XX:NewRatio=2",
75                                                              "-Xlog:gc+heap+ergo=debug",
76                                                              "-XX:NewSizeThreadIncrease="+expectedValue,
77                                                              GCTest.class.getName());
78     OutputAnalyzer output = new OutputAnalyzer(pb.start());
79 
80     output.shouldHaveExitValue(0);
81 
82     if (isNewsizeChanged) {
83       output.shouldContain(LOG_NEWSIZE_CHANGED);
84     } else {
85       output.shouldNotContain(LOG_NEWSIZE_CHANGED);
86     }
87   }
88 
89   static class GCTest {
90 
91     static final int MAX_THREADS_COUNT = 4;
92     static TestThread threads[] = new TestThread[MAX_THREADS_COUNT];
93 
main(String[] args)94     public static void main(String[] args) {
95 
96       System.out.println("Creating garbage");
97 
98       for (int i=0; i<MAX_THREADS_COUNT; i++) {
99         threads[i] = new TestThread();
100         threads[i].start();
101       }
102 
103       System.gc();
104 
105       for (int i=0; i<MAX_THREADS_COUNT; i++) {
106         threads[i].stopRunning();
107       }
108 
109       System.out.println("Done");
110     }
111 
112     private static class TestThread extends Thread {
113 
114       volatile boolean isRunning = true;
115 
run()116       public void run() {
117         while (isRunning == true) {
118           try {
119             Thread.sleep(10);
120           } catch (Throwable t) {
121           }
122         }
123       }
124 
stopRunning()125       public void stopRunning() {
126         isRunning = false;
127       }
128     }
129   }
130 }
131