blob: 3d5d0629f3d36cf883b4d0da67dad606852f59e0 [file] [log] [blame]
jeffhao5d1ac922011-09-29 17:41:15 -07001/*
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
Mathieu Chartiera61894d2015-04-23 16:32:54 -070017import java.lang.reflect.InvocationTargetException;
18import java.lang.reflect.Method;
19
jeffhao5d1ac922011-09-29 17:41:15 -070020public class Main {
21 static class ArrayMemEater {
Elliott Hughesff9af222013-04-11 18:13:31 -070022 static boolean sawOome;
23
24 static void blowup(char[][] holder) {
jeffhao5d1ac922011-09-29 17:41:15 -070025 try {
Elliott Hughesff9af222013-04-11 18:13:31 -070026 for (int i = 0; i < holder.length; ++i) {
Nicolas Geoffray74d6a822014-10-03 10:54:19 +000027 holder[i] = new char[1024 * 1024];
Elliott Hughesff9af222013-04-11 18:13:31 -070028 }
jeffhao5d1ac922011-09-29 17:41:15 -070029 } catch (OutOfMemoryError oome) {
Elliott Hughesff9af222013-04-11 18:13:31 -070030 ArrayMemEater.sawOome = true;
jeffhao5d1ac922011-09-29 17:41:15 -070031 }
jeffhao5d1ac922011-09-29 17:41:15 -070032 }
33 }
34
35 static class InstanceMemEater {
Elliott Hughesff9af222013-04-11 18:13:31 -070036 static boolean sawOome;
Mark Mendell8ed2e702014-08-18 22:19:06 -040037 static InstanceMemEater hook;
Elliott Hughesff9af222013-04-11 18:13:31 -070038
jeffhao5d1ac922011-09-29 17:41:15 -070039 InstanceMemEater next;
Elliott Hughesff9af222013-04-11 18:13:31 -070040 double d1, d2, d3, d4, d5, d6, d7, d8; // Bloat this object so we fill the heap faster.
jeffhao5d1ac922011-09-29 17:41:15 -070041
Elliott Hughesff9af222013-04-11 18:13:31 -070042 static InstanceMemEater allocate() {
jeffhao5d1ac922011-09-29 17:41:15 -070043 try {
Elliott Hughesff9af222013-04-11 18:13:31 -070044 return new InstanceMemEater();
jeffhao5d1ac922011-09-29 17:41:15 -070045 } catch (OutOfMemoryError e) {
Elliott Hughesff9af222013-04-11 18:13:31 -070046 InstanceMemEater.sawOome = true;
47 return null;
jeffhao5d1ac922011-09-29 17:41:15 -070048 }
jeffhao5d1ac922011-09-29 17:41:15 -070049 }
50
Elliott Hughesff9af222013-04-11 18:13:31 -070051 static void confuseCompilerOptimization(InstanceMemEater instance) {
Mark Mendell8ed2e702014-08-18 22:19:06 -040052 hook = instance;
jeffhao5d1ac922011-09-29 17:41:15 -070053 }
54 }
55
Vladimir Markoa35510d2017-01-16 22:42:09 +000056 public static Object eatAllMemory() {
57 Object[] result = null;
58 int size = 1000000;
59 while (result == null && size != 0) {
60 try {
61 result = new Object[size];
62 } catch (OutOfMemoryError oome) {
63 size /= 2;
64 }
65 }
66 if (result != null) {
67 int index = 0;
68 while (index != result.length && size != 0) {
69 try {
70 result[index] = new byte[size];
71 ++index;
72 } catch (OutOfMemoryError oome) {
73 size /= 2;
74 }
75 }
76 }
77 return result;
78 }
79
Nicolas Geoffray74d6a822014-10-03 10:54:19 +000080 static boolean triggerArrayOOM() {
81 ArrayMemEater.blowup(new char[128 * 1024][]);
Elliott Hughesff9af222013-04-11 18:13:31 -070082 return ArrayMemEater.sawOome;
jeffhao5d1ac922011-09-29 17:41:15 -070083 }
84
Elliott Hughesff9af222013-04-11 18:13:31 -070085 static boolean triggerInstanceOOM() {
86 InstanceMemEater memEater = InstanceMemEater.allocate();
jeffhao5d1ac922011-09-29 17:41:15 -070087 InstanceMemEater lastMemEater = memEater;
88 do {
Elliott Hughesff9af222013-04-11 18:13:31 -070089 lastMemEater.next = InstanceMemEater.allocate();
jeffhao5d1ac922011-09-29 17:41:15 -070090 lastMemEater = lastMemEater.next;
91 } while (lastMemEater != null);
92 memEater.confuseCompilerOptimization(memEater);
Mark Mendell8ed2e702014-08-18 22:19:06 -040093 InstanceMemEater.hook = null;
Elliott Hughesff9af222013-04-11 18:13:31 -070094 return InstanceMemEater.sawOome;
jeffhao5d1ac922011-09-29 17:41:15 -070095 }
96
97 public static void main(String[] args) {
Mathieu Chartiera61894d2015-04-23 16:32:54 -070098 if (triggerReflectionOOM()) {
99 System.out.println("Test reflection correctly threw");
100 }
Vladimir Markoa35510d2017-01-16 22:42:09 +0000101 if (triggerReflectionOOM2()) {
102 System.out.println("Test reflection2 correctly threw");
103 }
Mathieu Chartiera61894d2015-04-23 16:32:54 -0700104
Nicolas Geoffray74d6a822014-10-03 10:54:19 +0000105 if (triggerArrayOOM()) {
Elliott Hughesff9af222013-04-11 18:13:31 -0700106 System.out.println("NEW_ARRAY correctly threw OOME");
107 }
108
109 if (triggerInstanceOOM()) {
110 System.out.println("NEW_INSTANCE correctly threw OOME");
111 }
jeffhao5d1ac922011-09-29 17:41:15 -0700112 }
Mathieu Chartiera61894d2015-04-23 16:32:54 -0700113
114 static Object[] holder;
115
116 public static void blowup() throws Exception {
Mathieu Chartier30f530e2017-03-22 10:02:31 -0700117 int size = 2 * 1024 * 1024;
Mathieu Chartiera61894d2015-04-23 16:32:54 -0700118 for (int i = 0; i < holder.length; ) {
119 try {
120 holder[i] = new char[size];
121 i++;
122 } catch (OutOfMemoryError oome) {
Mathieu Chartier30f530e2017-03-22 10:02:31 -0700123 size = size / 16;
Mathieu Chartiera61894d2015-04-23 16:32:54 -0700124 if (size == 0) {
125 break;
126 }
127 }
128 }
129 holder[0] = new char[100000];
130 }
131
132 static boolean triggerReflectionOOM() {
133 try {
134 Class<?> c = Main.class;
Andreas Gampe166aaee2016-07-18 08:27:23 -0700135 Method m = c.getMethod("blowup");
Mathieu Chartiera61894d2015-04-23 16:32:54 -0700136 holder = new Object[1000000];
137 m.invoke(null);
138 holder = null;
139 System.out.println("Didn't throw from blowup");
140 } catch (OutOfMemoryError e) {
141 holder = null;
142 } catch (InvocationTargetException e) {
143 holder = null;
144 if (!(e.getCause() instanceof OutOfMemoryError)) {
145 System.out.println("InvocationTargetException cause not OOME " + e.getCause());
146 return false;
147 }
148 } catch (Exception e) {
149 holder = null;
150 System.out.println("Unexpected exception " + e);
151 return false;
152 }
153 return true;
154 }
Vladimir Markoa35510d2017-01-16 22:42:09 +0000155
156 static boolean triggerReflectionOOM2() {
157 Object memory = eatAllMemory();
158 boolean result = false;
159 try {
160 Main.class.getDeclaredMethods();
161 } catch (OutOfMemoryError e) {
162 result = true;
163 }
164 if (!result) {
165 boolean memoryWasAllocated = (memory != null);
166 memory = null;
167 System.out.println("memoryWasAllocated = " + memoryWasAllocated);
168 }
169 return result;
170 }
jeffhao5d1ac922011-09-29 17:41:15 -0700171}