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