1 /* 2 * Copyright (c) 2002, 2018, 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 //gctest02.java 24 25 26 /* 27 * @test 28 * @key gc 29 * 30 * @summary converted from VM Testbase gc/gctests/gctest02. 31 * VM Testbase keywords: [gc] 32 * 33 * @library /vmTestbase 34 * /test/lib 35 * @run driver jdk.test.lib.FileInstaller . . 36 * @run main/othervm gc.gctests.gctest02.gctest02 100 37 */ 38 39 package gc.gctests.gctest02; 40 41 import nsk.share.TestFailure; 42 import nsk.share.TestBug; 43 import nsk.share.test.LocalRandom; 44 45 /* stress testing 46 create 16 memory evil threads requesting to allocate 47 the object of sizes from 8 to ( 2 ^ 19). 48 The live time of objects is random (0 ~ 1000). 49 Here we let the threads that reference the objects 50 to simulate the object life time. 51 */ 52 53 import java.util.Random; 54 55 class PopulationException extends Exception { 56 //this exception is used to signal that we've 57 //reached the end of the test 58 } 59 60 class ThreadCount { 61 static int count= 0; 62 static synchronized void inc() { count++; } 63 static synchronized void dec() { count --; } 64 static synchronized int get() { return count; } 65 } 66 67 class Person { 68 String name; 69 int ssid; 70 int age; 71 int buf[]; 72 int bufsz; 73 static int populationCount = 0; 74 static int populationLimit = 0; 75 76 Person(String n, int ssid, int age, int bufsz) 77 throws PopulationException { 78 name = n; 79 this.ssid = ssid; 80 this.age = age; 81 if ( bufsz > 0 ) { 82 this.bufsz = bufsz; 83 this.buf = new int[bufsz]; 84 } 85 incPopulation(); 86 if (getPopulation() > getPopulationLimit()) { 87 throw new PopulationException(); 88 } 89 } 90 public static synchronized int getPopulationLimit() { 91 return populationLimit; 92 } 93 public static synchronized void setPopulationLimit(int newLimit) { 94 populationLimit = newLimit; 95 } 96 public static synchronized int getPopulation() { 97 return populationCount; 98 } 99 public static synchronized void incPopulation() { 100 populationCount ++; 101 } 102 103 } 104 105 // hr (humane resource) dept is using objects. 106 // Put the hr thread to sleep to keep the reference to objects 107 class hr extends Thread { 108 Person pp; 109 int lifetime; 110 111 hr(Person p, int l) { 112 pp = p; 113 lifetime = l; 114 } 115 116 public void run() { 117 // just sleep to emulate the life time of object referenced by p 118 try { sleep(lifetime); } 119 catch (InterruptedException e) {} 120 } 121 } 122 123 class Memevil extends Thread { 124 int sum; 125 int bufsz = 64; 126 boolean debug = false; 127 128 Memevil(int bufsz) { 129 sum = 0; 130 this.bufsz = bufsz; 131 } 132 /* Person object is live short, it will be garbage after 133 * control returns 134 */ 135 private boolean doit() { 136 try { 137 Person p = new Person("Duke", 100, 100, bufsz); 138 hr useit = new hr(p, (int)(100*LocalRandom.random())); 139 useit.start(); 140 return true; 141 } 142 catch (PopulationException e) { 143 return false; 144 } 145 catch (OutOfMemoryError e ) { 146 System.err.println(getName() + ": Out of Memory"); 147 return false; 148 } 149 } 150 public void run() { 151 while ( doit() ) { 152 if ( LocalRandom.random() > 0.6668) { 153 try { 154 sleep(10); // to be nice 155 } 156 catch (InterruptedException e) { 157 } 158 } 159 Thread.yield(); 160 } 161 //we've reached the population limit, so we're exiting the thread 162 ThreadCount.dec(); 163 } 164 } 165 166 class Escaper extends Thread { 167 public void run() { 168 while ( ThreadCount.get() > 0 ) { 169 int buf[] = new int[32]; 170 { 171 Thread.yield(); 172 } 173 } 174 } 175 } 176 177 public class gctest02 { 178 public static void main(String args[] ) { 179 int bufsz = 8; 180 int peopleLimit = 1000; 181 Memevil me=null; 182 if (args.length > 0) 183 { 184 try 185 { 186 peopleLimit = new Integer(args[0]).intValue(); 187 } 188 catch (NumberFormatException e) 189 { 190 throw new TestBug( 191 "Bad input to gctest02. Expected integer, got: ->" 192 + args[0] + "<-", e); 193 } 194 } 195 196 Person.setPopulationLimit(peopleLimit); 197 for (int ii=0; ii<40; ii++) { 198 bufsz = 8; 199 Person.populationCount = 0; 200 Escaper you = new Escaper(); 201 you.setName("Escaper"); 202 ThreadCount.inc(); 203 you.start(); 204 me = new Memevil(bufsz); 205 me.setName("Memevil" + bufsz); 206 bufsz = 2*bufsz; 207 me.start(); 208 Thread.yield(); 209 for (int i=1; i<11; i++) { 210 ThreadCount.inc(); 211 me = new Memevil(bufsz); 212 me.setName("Memevil" + bufsz); 213 bufsz = 2*bufsz; 214 me.start(); 215 Thread.yield(); 216 } 217 try { 218 you.join(); 219 } 220 catch (InterruptedException e) { 221 throw new TestFailure("InterruptedException in gctest2.main()"); 222 } 223 for (int i=1; i<11; i++) { 224 try { me.join(); } 225 catch (InterruptedException e) { 226 throw new TestFailure("InterruptedException in gctest2.main()"); 227 } 228 } 229 } 230 System.out.println("Test passed."); 231 } 232 }