Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except001.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/except001.29* VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]30* VM testbase readme:31* DESCRIPTION32* This checks if OutOfMemoryError exception is correctly enwrapped into33* InvocationTargetException when thrown inside a method invoked via34* reflection.35* The test tries to occupy all of memory available in the heap by36* allocating lots of new Object() instances. Instances of the "empty"37* type Object are the smallest objects, so they apparently should occupy38* most fine-grained fragments in the heap. Thus, there apparently should39* not remain any free space to incarnate new Throwable instance, and VM40* possibly could crash while trying to throw new OutOfMemoryError and41* enwrap it into new InvocationTargetException instance.42* By the way, the test checks time elapsed to allocate memory. Both43* classic VM and HotSpot seem to fall into poor performance of memory44* allocation when heap is almost over. E.g.: HotSpot 1.3-betaH may spend45* more than 1 minute to allocate next Object in this case (tested on46* Pentium-II, 350MHz, 128Mb RAM). To avoid this problem, the test enforce47* OutOfMemoryError if more then 5 minutes is spent to allocate "last bytes"48* of memory.49* COMMENTS50* HotSpot releases 1.0-fcsE (both Win32 and Sparc), and 1.3-betaH (Win32)51* fail on this test due to poor performance of memory allocation.52* #4248801 (P3/S5) slow memory allocation when heap is almost exhausted53* Despite this bug is treated fixed in HotSpot 1.0.1, it still does suffer54* slow memory allocation when running on PC having 64Mb or less of RAM.55* There is also a workaround involved to avoid the following bugs known56* for HotSpot and for classic VM:57* #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)58* #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)59* However, printing of the test's error messages, warnings, and of execution60* trace may fail under JDK 1.2 for Win32 even so.61* HotSpot 2.0-devA (Win32) crashes due to the known HotSpot bug:62* #4239828 (P1/S4) 1.3c1: VM crashes when heap is exhausted63*64* @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except00165*/6667package nsk.stress.except;6869import java.io.PrintStream;70import java.lang.reflect.InvocationTargetException;71import java.lang.reflect.Method;7273/**74* This checks if <code>OutOfMemoryError</code> exception is correctly75* enwrapped into <code>InvocationTargetException</code> when thrown inside76* a method invoked via reflection.77* <p>78* <p>The test tries to occupy all of memory available in the heap by79* allocating lots of new <code>Object()</code> instances. Instances of the80* ``empty'' type <code>Object</code> are the smallest objects, so they81* apparently should occupy most fine-grained fragments in the heap.82* Thus, there apparently should not remain any free space to incarnate new83* <code>Throwable</code> instance, and VM possibly could crash while trying84* to throw new <code>OutOfMemoryError</code> and enwrap it into new85* <code>InvocationTargetException</code> instance.86* <p>87* <p>By the way, the test checks time elapsed to allocate memory.88* Both classic VM and HotSpot seem to fall into poor performance of memory89* allocation when heap is almost over. E.g.: HotSpot 1.3-betaH may spend90* more than 1 minute to allocate next <code>Object</code> in this case91* (tested on Pentium-II, 350MHz, 128Mb RAM). To workaround this problem,92* the test enforces <code>OutOfMemoryError</code> if more then 5 minutes93* is spent to allocate ``last bytes'' of the memory.94*/95public class except001 {96/**97* This field allows or supresses printing with <code>display()</code>98* method.99*100* @see #display(Object)101* @see #complain(Object)102* @see #out103*/104private static boolean MODE_VERBOSE = true;105/*106* Storage for a lot of tiny objects107* "static volatile" keywords are for preventing heap optimization108*/109private static volatile Object pool[] = null;110111/**112* Print execution trace if <code>MODE_VERBOSE</code> is <code>true</code>113* (optional).114*115* @see #MODE_VERBOSE116* @see #complain(Object)117* @see #out118*/119private static void display(Object message) {120if (MODE_VERBOSE)121out.println(message.toString());122out.flush();123}124125/**126* Print error <code>message</code>.127*128* @see #display(Object)129* @see #out130*/131private static void complain(Object message) {132out.println("# " + message);133out.flush();134}135136/**137* The log-stream assigned at runtime by the method138* <code>run(args,out)</code>.139*140* @see #display(Object)141* @see #complain(Object)142* @see #run(String[], PrintStream)143*/144private static PrintStream out;145146/**147* Try to allocate lots of instances of the type <code>Object</code>.148* Such instances are most fine-grained, and thus they should occupy149* smallest fragments of free memory in the heap.150* <p>151* <p>By the way, break the test, if JVM has spent more than152* 5 minutes to allocate latest portions of memory.153*/154public static void raiseOutOfMemory() throws OutOfMemoryError {155try {156// Repository for objects, which should be allocated:157int index = 0;158for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)159try {160pool = new Object[size];161} catch (OutOfMemoryError oome) {162}163if (pool == null)164throw new Error("HS bug: cannot allocate new Object[1]");165166// Sum up time spent, when it was hard to JVM to allocate next object167// (i.e.: when JVM has spent more than 1 second to allocate new object):168double totalDelay = 0;169long timeMark = System.currentTimeMillis();170171for (; index < pool.length; index++) {172//-------------------------173pool[index] = new Object();174long nextTimeMark = System.currentTimeMillis();175long elapsed = nextTimeMark - timeMark;176timeMark = nextTimeMark;177//----------------------178if (elapsed > 1000) {179double seconds = elapsed / 1000.0;180display(181"pool[" + index +182"]=new Object(); // elapsed " + seconds + "s");183totalDelay += seconds;184if (totalDelay > 300) {185complain(186"Memory allocation became slow: so heap seems exhausted.");187throw new OutOfMemoryError();188}189}190}191192// This method should never return:193throw new Error("TEST_BUG: failed to provoke OutOfMemoryError");194} finally {195// Make sure there will be enough memory for next object allocation196pool = null;197}198}199200/**201* Invoke the method <code>raiseOutOfMemory()</code> with reflection,202* and check if the exception it throws is just203* <code>OutOfMemoryError</code> enwrapped into204* <code>InvocationTargetException</code> instance.205* <p>206* <p>Before the test begins, <code>this.out</code> filed is assigned207* to the parameter <code>out</code>. Parameter <code>args[]</code>208* is ignored.209*210* @see #raiseOutOfMemory()211*/212public static int run(String args[], PrintStream out) {213out.println("# While printing this message, JVM seems to initiate the output");214out.println("# stream, so that it will not need more memory to print later,");215out.println("# when the heap would fail to provide more memory.");216out.println("# ");217out.println("# That problem is caused by the known JDK/HotSpot bugs:");218out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");219out.println("# 4245060 (P4/S5) poor garbage collector performance");220out.println("# ");221out.println("# This message is just intended to work-around that problem.");222out.println("# If printing should fail even so.");223224if (args.length > 0) {225if (args[0].toLowerCase().startsWith("-v"))226MODE_VERBOSE = true;227}228229except001.out = out;230Class testClass = except001.class;231try {232Method testMethod = testClass.getMethod("raiseOutOfMemory", new Class [0]);233Object junk = testMethod.invoke(null, new Object [0]);234235} catch (InvocationTargetException ite) {236Throwable targetException = ite.getTargetException();237if (targetException instanceof OutOfMemoryError) {238display("OutOfMemoryError thrown as expected.");239display("Test passed.");240return 0;241}242complain("Unexpected InvocationTargetException: " + targetException);243complain("Test failed.");244return 2;245246} catch (Exception exception) {247complain("Unexpected exception: " + exception);248complain("Test failed.");249return 2;250}251//252complain("The test has finished unexpectedly.");253complain("Test failed.");254return 2;255}256257/**258* Re-call to <code>run(args,out)</code>, and return JCK-like exit status.259* (The stream <code>out</code> is assigned to <code>System.out</code> here.)260*261* @see #run(String[], PrintStream)262*/263public static void main(String args[]) {264Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {265// Last try. If there is some exception outside the code, test should end correctly266@Override267public void uncaughtException(Thread t, Throwable e) {268try {269pool = null;270System.gc();271if (e instanceof OutOfMemoryError) {272try {273System.out.println("OOME : Test Skipped");274System.exit(95);275} catch (Throwable ignore) {276} // No code in the handler can provoke correct exceptions.277} else {278e.printStackTrace();279throw (RuntimeException) e;280}281} catch (OutOfMemoryError oome) {282}283}284});285int exitCode = run(args, System.out);286System.exit(exitCode + 95);287// JCK-like exit status.288}289290}291292293