Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except008.java
41155 views
/*1* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22232425/*26* @test27* @key stress28*29* @summary converted from VM testbase nsk/stress/except/except008.30* VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]31* VM testbase readme:32* DESCRIPTION33* This checks if various exceptions are thrown (and caught) correctly34* when there apparently are no free space in the heap to allocate new35* Throwable instance.36* The test tries to occupy all of memory available in the heap by allocating37* lots of new Object() instances. Instances of the type Object are the smallest38* objects, so they apparently should occupy most fine-grained fragments in the39* heap and leave no free space for new Throwable instance. After that, the test40* provokes various exceptions (e.g.: by executing integer division by 0 and so41* on), and checks if appropriate exceptions are thrown.42* COMMENTS43* The test needs a lot of memory to start up, so it should not run under older44* JDK 1.1.x release due to its poorer heap utilization. Also, some checks are45* skipped when testing classic VM, because OutOfMemoryError is correctly thrown46* instead of target exception.47* When the test is being self-initiating (i.e.: eating heap), memory occupation48* is terminated if memory allocation slows down crucially. This is a workaround49* intended to avoid the HotSpot bug:50* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted51* There is also a workaround involved to avoid the following bugs known52* for HotSpot and for classic VM:53* #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)54* #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)55* However, printing of the test's error messages, warnings, and of execution56* trace fails under JDK 1.2 for Win32 even so. If the test fails due to this57* problem, exit status 96 is returned instead of 97.58* JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:59* #4245057 (P2/S3) VM crashes when heap is exhausted60*61* @run main/othervm -Xms50M -Xmx200M -XX:-UseGCOverheadLimit nsk.stress.except.except00862*/6364package nsk.stress.except;6566import java.io.PrintStream;67import java.lang.reflect.Field;68import java.lang.reflect.Method;6970/**71* This checks if various exceptions are thrown (and caught) correctly72* when there apparently are no free space in the heap to allocate new73* <code>Throwable</code> instance.74* <p>75* <p>The test tries to occupy all of memory available in the heap by76* allocating lots of new <code>Object()</code> instances. Instances of the77* type <code>Object</code> are the smallest objects, so they apparently should78* occupy most fine-grained fragments in the heap and leave no free space for79* new <code>Throwable</code> instance. After that, the test provokes various80* exceptions (e.g.: by executing integer division by 0 and so on), and checks81* if appropriate exceptions are thrown.82* <p>83* <p>Note, that memory occupation is terminated if memory allocation slows84* down crucially. This is a workaround intended to avoid the HotSpot bug:85* <br> 86* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted87* <p>88* <p>There is also a workaround involved to avoid the following bugs known89* for HotSpot and for classic VM:90* <br> 91* #4239841 (P1/S5) 1.1: poor garbage collector performance92* <br> 93* #4245060 (P4/S5) poor garbage collector performance94* <br>However, printing of the test's error messages, warnings, and of95* execution trace may fail even so. If the test fails due to poor GC96* performance, exit status 96 is returned instead of 97.97* <p>98* <p>Also note, that the test needs a lot of memory to start up, so it should99* not run under older JDK 1.1.x release due to its poor heap utilization.100*/101public class except008 {102/**103* Either allow or supress printing of execution trace.104*/105private static boolean TRACE_ON = false;106/**107* Either allow or supress printing of warning messages.108*/109private static final boolean WARN_ON = true;110/*111* Storage for a lot of tiny objects112* "static volatile" keywords are for preventing heap optimization113*/114private static volatile Object pool[] = null;115/**116* Temporary <code>log</code> for error messages, warnings and/or execution trace.117*118* @see #messages119*/120private static String log[] = new String[1000]; // up to 1000 messages121/**122* How many <code>messages</code> were submitted to the <code>log</code>.123*124* @see #log125*/126private static int messages = 0;127128/**129* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),130* and print the test summary - either test passed of failed.131*/132public static int run(String args[], PrintStream out) {133if (args.length > 0) {134if (args[0].toLowerCase().startsWith("-v"))135TRACE_ON = true;136}137138int exitCode = run(out);139pool = null;140System.gc();141// Print the log[] and the test summary:142try {143for (int i = 0; i < messages; i++)144out.println(log[i]);145if (exitCode == 0) {146if (TRACE_ON)147out.println("Test passed.");148} else149out.println("Test failed.");150} catch (OutOfMemoryError oome) {151// Poor performance of garbage collector:152exitCode = 1;153}154155return exitCode;156}157158/**159* Allocate as much <code>Object</code> instances as possible to bring JVM160* into stress, and then check if exceptions are correctly thrown accordingly161* to various situations like integer division by 0, etc.162*/163private static int run(PrintStream out) {164out.println("# While printing this message, JVM seems to initiate the output");165out.println("# stream, so that it will not need more memory to print later,");166out.println("# when the heap would fail to provide more memory.");167out.println("# ");168out.println("# Note, that the test maintains especial static log[] field in");169out.println("# order to avoid printing when the heap seems exhausted.");170out.println("# Nevertheless, printing could arise OutOfMemoryError even");171out.println("# after all the memory allocated by the test is released.");172out.println("# ");173out.println("# That problem is caused by the known JDK/HotSpot bugs:");174out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");175out.println("# 4245060 (P4/S5) poor garbage collector performance");176out.println("# ");177out.println("# This message is just intended to work-around that problem.");178out.println("# If printing should fail even so, the test will try to return");179out.println("# the exit status 96 instead of 97 to indicate the problem.");180out.println("# However, the test may fail or even crash on some platforms");181out.println("# suffering the bug 4239841 or 4245060.");182183// Prepare some items, which will be used by the test:184Zoo zoo = new Zoo(); // load the class Zoo185Class noArgs[] = new Class[0];186187// Sum up exit code:188int exitCode = 0; // apparently PASSED189int skipped = 0; // some checks may correctly suffer OutOfMemoryError190191// Allocate repository for a lots of tiny objects:192for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)193try {194pool = new Object[size];195} catch (OutOfMemoryError oome) {196}197if (pool == null)198throw new Error("HS bug: cannot allocate new Object[1]");199int poolSize = pool.length;200201int index = 0;202pool[index++] = new Object();203204// Sum up time spent, when it was hard to JVM to allocate next object205// (i.e.: when JVM has spent more than 1 second to allocate new object):206double totalDelay = 0;207long timeMark = System.currentTimeMillis();208try {209for (; index < poolSize; index++) {210//-------------------------211pool[index] = new Object();212long nextTimeMark = System.currentTimeMillis();213long elapsed = nextTimeMark - timeMark;214timeMark = nextTimeMark;215//----------------------216if (elapsed > 1000) {217double seconds = elapsed / 1000.0;218if (TRACE_ON)219out.println(220"pool[" + index + "]=new Object(); // elapsed " + seconds + "s");221totalDelay += seconds;222if (totalDelay > 60) {223if (TRACE_ON)224out.println(225"Memory allocation became slow; so, heap seems exhausted.");226break;227}228}229}230} catch (OutOfMemoryError oome) {231if (TRACE_ON)232log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";233}234235if (index > poolSize - 1000) {236if (WARN_ON)237log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";238}239240// Check NoSuchFieldException (positive):241try {242Field valid = Zoo.class.getField("PUBLIC_FIELD"); // should pass243// Field wrong = Zoo.class.getField("PRIVATE_FIELD"); // should fail244if (TRACE_ON)245log[messages++] = "Success: NoSuchFieldException not thrown as expected";246} catch (NoSuchFieldException nsfe) {247pool[index++] = nsfe;248log[messages++] = "Failure: NoSuchFieldException thrown unexpectedly";249exitCode = 2;250} catch (OutOfMemoryError oome) {251if (WARN_ON)252log[messages++] =253"Skipped: NoSuchFieldException positive check - OutOfMemoryError thrown";254skipped++;255}256257// Check NoSuchFieldException (negative):258try {259// Field valid = Zoo.class.getField("PUBLIC_FIELD"); // should pass260Field wrong = Zoo.class.getField("PRIVATE_FIELD"); // should fail261log[messages++] = "Failure: NoSuchFieldException incorrectly not thrown";262exitCode = 2;263} catch (NoSuchFieldException nsfe) {264if (TRACE_ON)265log[messages++] = "Success: NoSuchFieldException thrown as expected";266} catch (OutOfMemoryError oome) {267if (WARN_ON)268log[messages++] =269"NoSuchFieldException negative check - OutOfMemoryError thrown";270skipped++;271}272273// Check NoSuchMethodException (positive):274try {275Method valid = Zoo.class.getMethod("PUBLIC_METHOD", noArgs); // should pass276// Method wrong = Zoo.class.getMethod("PRIVATE_METHOD",noArgs); // should fail277if (TRACE_ON)278log[messages++] = "Success: NoSuchFieldException not thrown as expected";279} catch (NoSuchMethodException nsme) {280pool[index++] = nsme;281log[messages++] = "Failure: NoSuchMethodException thrown unexpectedly";282exitCode = 2;283} catch (OutOfMemoryError oome) {284if (WARN_ON)285log[messages++] =286"Skipped: NoSuchMethodException positive check - OutOfMemoryError thrown";287pool[index++] = oome;288skipped++;289}290291// Check NoSuchMethodException (negative):292try {293// Method valid = Zoo.class.getMethod("PUBLIC_METHOD",noArgs); // should pass294Method wrong = Zoo.class.getMethod("PRIVATE_METHOD", noArgs); // should fail295log[messages++] = "Failure: NoSuchMethodException incorrectly not thrown";296exitCode = 2;297} catch (NoSuchMethodException nsme) {298pool[index++] = nsme;299if (TRACE_ON)300log[messages++] = "Success: NoSuchFieldException thrown as expected";301} catch (OutOfMemoryError oome) {302if (WARN_ON)303log[messages++] =304"Skipped: NoSuchMethodException negative check - OutOfMemoryError thrown";305skipped++;306}307308return exitCode;309}310311/**312* Several items used to check reflections.313*/314private static class Zoo {315public String PUBLIC_FIELD = "Accessible via reflection";316private String PRIVATE_FIELD = "Inaccessible via reflection";317318public String PUBLIC_METHOD() {319return "Accessible via reflection";320}321322private String PRIVATE_METHOD() {323return "Inaccessible via reflection";324}325326}327328/**329* Re-call to <code>run(args,out)</code>, and return JCK-like exit status.330* (The stream <code>out</code> is assigned to <code>System.out</code> here.)331*332* @see #run(String[], PrintStream)333*/334public static void main(String args[]) {335Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {336// Last try. If there is some exception outside the code, test should end correctly337@Override338public void uncaughtException(Thread t, Throwable e) {339try {340pool = null;341log = null;342System.gc();343if (e instanceof OutOfMemoryError) {344try {345System.out.println("OOME : Test Skipped");346System.exit(0);347} catch (Throwable ignore) {348} // No code in the handler can provoke correct exceptions.349} else {350e.printStackTrace();351throw (RuntimeException) e;352}353} catch (OutOfMemoryError oome) {354}355}356});357int exitCode = run(args, System.out);358System.exit(exitCode + 95);359// JCK-like exit status.360}361362}363364365