Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except003.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*/222324/*25* @test26* @key stress27*28* @summary converted from VM testbase nsk/stress/except/except003.29* VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]30* VM testbase readme:31* DESCRIPTION32* This checks if various exceptions are thrown (and caught) correctly33* when there apparently are no free space in the heap to allocate new34* Throwable instance.35* The test tries to occupy all of memory available in the heap by allocating36* lots of new Object() instances. Instances of the type Object are the smallest37* objects, so they apparently should occupy most fine-grained fragments in the38* heap and leave no free space for new Throwable instance. After that, the test39* provokes various exceptions (e.g.: by executing integer division by 0 and so40* on), and checks if appropriate exceptions are thrown.41* COMMENTS42* The test needs a lot of memory to start up, so it should not run under older43* JDK 1.1.x release due to its poorer heap utilization. Also, some checks are44* skipped when testing classic VM, because OutOfMemoryError is correctly thrown45* instead of target exception.46* When the test is being self-initiating (i.e.: eating heap), memory occupation47* is terminated if memory allocation slows down crucially. This is a workaround48* intended to avoid the HotSpot bug:49* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted50* There is also a workaround involved to avoid the following bugs known51* for HotSpot and for classic VM:52* #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)53* #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)54* However, printing of the test's error messages, warnings, and of execution55* trace fails under JDK 1.2 for Win32 even so. If the test fails due to this56* problem, exit status 96 is returned instead of 97.57* JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:58* #4245057 (P2/S3) VM crashes when heap is exhausted59*60* @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except00361*/6263package nsk.stress.except;6465import java.io.PrintStream;6667/**68* This checks if various exceptions are thrown (and caught) correctly69* when there apparently are no free space in the heap to allocate new70* <code>Throwable</code> instance.71* <p>72* <p>The test tries to occupy all of memory available in the heap by73* allocating lots of new <code>Object()</code> instances. Instances of the74* type <code>Object</code> are the smallest objects, so they apparently should75* occupy most fine-grained fragments in the heap and leave no free space for76* new <code>Throwable</code> instance. After that, the test provokes various77* exceptions (e.g.: by executing integer division by 0 and so on), and checks78* if appropriate exceptions are thrown.79* <p>80* <p>Note, that memory occupation is terminated if memory allocation slows81* down crucially. This is a workaround intended to avoid the HotSpot bug:82* <br> 83* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted84* <p>85* <p>There is also a workaround involved to avoid the following bugs known86* for HotSpot and for classic VM:87* <br> 88* #4239841 (P1/S5) 1.1: poor garbage collector performance89* <br> 90* #4245060 (P4/S5) poor garbage collector performance91* <br>However, printing of the test's error messages, warnings, and of92* execution trace may fail even so. If the test fails due to poor GC93* performance, exit status 96 is returned instead of 97.94* <p>95* <p>Also note, that the test needs a lot of memory to start up, so it should96* not run under older JDK 1.1.x release due to its poor heap utilization.97*/98public class except003 {99/**100* Either allow or supress printing of execution trace.101*/102private static boolean TRACE_ON = false;103/**104* Either allow or supress printing of warning messages.105*/106private static final boolean WARN_ON = true;107/*108* Storage for a lot of tiny objects109* "static volatile" keywords are for preventing heap optimization110*/111private static volatile Object pool[] = null;112/**113* Temporary <code>log</code> for error messages, warnings and/or execution trace.114*115* @see #messages116*/117private static String log[] = new String[1000]; // up to 1000 messages118/**119* How many <code>messages</code> were submitted to the <code>log</code>.120*121* @see #log122*/123private static int messages = 0;124125/**126* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),127* and print the test summary - either test passed of failed.128*/129public static int run(String args[], PrintStream out) {130if (args.length > 0) {131if (args[0].toLowerCase().startsWith("-v"))132TRACE_ON = true;133}134135int exitCode = run(out);136pool = null;137System.gc();138// Print the log[] and the test summary:139try {140for (int i = 0; i < messages; i++)141out.println(log[i]);142if (exitCode == 0) {143if (TRACE_ON)144out.println("Test passed.");145} else146out.println("Test failed.");147} catch (OutOfMemoryError oome) {148// Poor performance of garbage collector:149exitCode = 1;150}151152return exitCode;153}154155/**156* Allocate as much <code>Object</code> instances as possible to bring JVM157* into stress, and then check if exceptions are correctly thrown accordingly158* to various situations like integer division by 0, etc.159*/160private static int run(PrintStream out) {161out.println("# While printing this message, JVM seems to initiate the output");162out.println("# stream, so that it will not need more memory to print later,");163out.println("# when the heap would fail to provide more memory.");164out.println("# ");165out.println("# Note, that the test maintains especial static log[] field in");166out.println("# order to avoid printing when the heap seems exhausted.");167out.println("# Nevertheless, printing could arise OutOfMemoryError even");168out.println("# after all the memory allocated by the test is released.");169out.println("# ");170out.println("# That problem is caused by the known JDK/HotSpot bugs:");171out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");172out.println("# 4245060 (P4/S5) poor garbage collector performance");173out.println("# ");174out.println("# This message is just intended to work-around that problem.");175out.println("# If printing should fail even so, the test will return the");176out.println("# exit status 96 instead of 97 to indicate the problem.");177178// Prepare some items, which will be used by the test:179Object trash = null;180181// Allocate repository for a lots of tiny objects:182pool = null;183// Sum up exit code:184int exitCode = 0; // apparently PASSED185int skipped = 0; // some checks may correctly suffer OutOfMemoryError186for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)187try {188pool = new Object[size];189} catch (OutOfMemoryError oome) {190}191if (pool == null)192throw new Error("HS bug: cannot allocate new Object[1]");193int poolSize = pool.length;194int index = 0;195196// Sum up time spent, when it was hard to JVM to allocate next object197// (i.e.: when JVM has spent more than 1 second to allocate new object):198double totalDelay = 0;199long timeMark = System.currentTimeMillis();200try {201for (; index < poolSize; index++) {202//-------------------------203pool[index] = new Object();204long nextTimeMark = System.currentTimeMillis();205long elapsed = nextTimeMark - timeMark;206timeMark = nextTimeMark;207//----------------------208if (elapsed > 1000) {209double seconds = elapsed / 1000.0;210if (TRACE_ON)211out.println(212"pool[" + index + "]=new Object(); // elapsed " + seconds + "s");213totalDelay += seconds;214if (totalDelay > 60) {215if (TRACE_ON)216out.println(217"Memory allocation became slow; so, heap seems exhausted.");218break;219}220}221}222} catch (OutOfMemoryError oome) {223if (TRACE_ON)224log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";225226// Do not release any byte once allocated:227pool[index++] = oome;228}229230if (index > poolSize - 1000) {231if (WARN_ON)232log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";233}234235// Check ClassNotFoundException (negative):236try {237// trash = Class.forName("nsk.stress.except.except003$Abra$Cadabra"); // correct - should pass238trash = Class.forName("nsk.stress.except.except003.Abra.Cadabra"); // incorrect - should fail239log[messages++] = "Failure: ClassNotFoundException (negative)";240exitCode = 2;241} catch (ClassNotFoundException cnfe) {242if (TRACE_ON)243log[messages++] = "Success: ClassNotFoundException (negative)";244} catch (OutOfMemoryError oome) {245if (WARN_ON)246log[messages++] = "Skipped: ClassNotFoundException (negative)";247skipped++;248}249250return exitCode;251}252253/**254* Re-call to <code>run(args,out)</code>, and return JCK-like exit status.255* (The stream <code>out</code> is assigned to <code>System.out</code> here.)256*257* @see #run(String[], PrintStream)258*/259public static void main(String args[]) {260Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {261// Last try. If there is some exception outside the code, test should end correctly262@Override263public void uncaughtException(Thread t, Throwable e) {264try {265pool = null;266log = null;267System.gc();268if (e instanceof OutOfMemoryError) {269try {270System.out.println("OOME : Test Skipped");271System.exit(95);272} catch (Throwable ignore) {273} // No code in the handler can provoke correct exceptions.274} else {275e.printStackTrace();276throw (RuntimeException) e;277}278} catch (OutOfMemoryError oome) {279}280}281});282int exitCode = run(args, System.out);283System.exit(exitCode + 95);284// JCK-like exit status.285}286287/**288* This class should be used to check <code>ClassNotFoundException</code>289* and <code>IllegalAccessException</code>.290*/291private static class Abra {292/**293* Will try to incorrectly find this class as <code>Cadabra</code>294* instead of <code>Abra$Cadabra</code>.295*/296public static class Cadabra {297}298299}300301}302303304