1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.lang.reflect.InvocationTargetException; 18 import java.lang.reflect.Method; 19 20 public class Main { 21 static class ArrayMemEater { 22 static boolean sawOome; 23 blowup(char[][] holder)24 static void blowup(char[][] holder) { 25 try { 26 for (int i = 0; i < holder.length; ++i) { 27 holder[i] = new char[1024 * 1024]; 28 } 29 } catch (OutOfMemoryError oome) { 30 ArrayMemEater.sawOome = true; 31 } 32 } 33 } 34 35 static class InstanceMemEater { 36 static boolean sawOome; 37 static InstanceMemEater hook; 38 39 InstanceMemEater next; 40 double d1, d2, d3, d4, d5, d6, d7, d8; // Bloat this object so we fill the heap faster. 41 allocate()42 static InstanceMemEater allocate() { 43 try { 44 return new InstanceMemEater(); 45 } catch (OutOfMemoryError e) { 46 InstanceMemEater.sawOome = true; 47 return null; 48 } 49 } 50 confuseCompilerOptimization(InstanceMemEater instance)51 static void confuseCompilerOptimization(InstanceMemEater instance) { 52 hook = instance; 53 } 54 } 55 triggerArrayOOM()56 static boolean triggerArrayOOM() { 57 ArrayMemEater.blowup(new char[128 * 1024][]); 58 return ArrayMemEater.sawOome; 59 } 60 triggerInstanceOOM()61 static boolean triggerInstanceOOM() { 62 InstanceMemEater memEater = InstanceMemEater.allocate(); 63 InstanceMemEater lastMemEater = memEater; 64 do { 65 lastMemEater.next = InstanceMemEater.allocate(); 66 lastMemEater = lastMemEater.next; 67 } while (lastMemEater != null); 68 memEater.confuseCompilerOptimization(memEater); 69 InstanceMemEater.hook = null; 70 return InstanceMemEater.sawOome; 71 } 72 main(String[] args)73 public static void main(String[] args) { 74 if (triggerReflectionOOM()) { 75 System.out.println("Test reflection correctly threw"); 76 } 77 78 if (triggerArrayOOM()) { 79 System.out.println("NEW_ARRAY correctly threw OOME"); 80 } 81 82 if (triggerInstanceOOM()) { 83 System.out.println("NEW_INSTANCE correctly threw OOME"); 84 } 85 } 86 87 static Object[] holder; 88 blowup()89 public static void blowup() throws Exception { 90 int size = 32 * 1024 * 1024; 91 for (int i = 0; i < holder.length; ) { 92 try { 93 holder[i] = new char[size]; 94 i++; 95 } catch (OutOfMemoryError oome) { 96 size = size / 2; 97 if (size == 0) { 98 break; 99 } 100 } 101 } 102 holder[0] = new char[100000]; 103 } 104 triggerReflectionOOM()105 static boolean triggerReflectionOOM() { 106 try { 107 Class<?> c = Main.class; 108 Method m = c.getMethod("blowup", (Class[]) null); 109 holder = new Object[1000000]; 110 m.invoke(null); 111 holder = null; 112 System.out.println("Didn't throw from blowup"); 113 } catch (OutOfMemoryError e) { 114 holder = null; 115 } catch (InvocationTargetException e) { 116 holder = null; 117 if (!(e.getCause() instanceof OutOfMemoryError)) { 118 System.out.println("InvocationTargetException cause not OOME " + e.getCause()); 119 return false; 120 } 121 } catch (Exception e) { 122 holder = null; 123 System.out.println("Unexpected exception " + e); 124 return false; 125 } 126 return true; 127 } 128 } 129