15d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/* 25d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Copyright (C) 2009 The Android Open Source Project 35d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * 45d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Licensed under the Apache License, Version 2.0 (the "License"); 55d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * you may not use this file except in compliance with the License. 65d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * You may obtain a copy of the License at 75d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * 85d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * http://www.apache.org/licenses/LICENSE-2.0 95d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * 105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Unless required by applicable law or agreed to in writing, software 115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * distributed under the License is distributed on an "AS IS" BASIS, 125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * See the License for the specific language governing permissions and 145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * limitations under the License. 155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 17a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartierimport java.lang.reflect.InvocationTargetException; 18a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartierimport java.lang.reflect.Method; 19a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier 205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class Main { 215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao static class ArrayMemEater { 22ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes static boolean sawOome; 23ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes 24ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes static void blowup(char[][] holder) { 255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao try { 26ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes for (int i = 0; i < holder.length; ++i) { 2774d6a8221c11ac4aa72808863db423aca44117f2Nicolas Geoffray holder[i] = new char[1024 * 1024]; 28ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes } 295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } catch (OutOfMemoryError oome) { 30ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes ArrayMemEater.sawOome = true; 315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao static class InstanceMemEater { 36ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes static boolean sawOome; 378ed2e706870c05411f0836b291263689aa1c6959Mark Mendell static InstanceMemEater hook; 38ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes 395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao InstanceMemEater next; 40ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes double d1, d2, d3, d4, d5, d6, d7, d8; // Bloat this object so we fill the heap faster. 415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 42ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes static InstanceMemEater allocate() { 435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao try { 44ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes return new InstanceMemEater(); 455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } catch (OutOfMemoryError e) { 46ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes InstanceMemEater.sawOome = true; 47ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes return null; 485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 51ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes static void confuseCompilerOptimization(InstanceMemEater instance) { 528ed2e706870c05411f0836b291263689aa1c6959Mark Mendell hook = instance; 535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 5674d6a8221c11ac4aa72808863db423aca44117f2Nicolas Geoffray static boolean triggerArrayOOM() { 5774d6a8221c11ac4aa72808863db423aca44117f2Nicolas Geoffray ArrayMemEater.blowup(new char[128 * 1024][]); 58ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes return ArrayMemEater.sawOome; 595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 61ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes static boolean triggerInstanceOOM() { 62ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes InstanceMemEater memEater = InstanceMemEater.allocate(); 635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao InstanceMemEater lastMemEater = memEater; 645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao do { 65ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes lastMemEater.next = InstanceMemEater.allocate(); 665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao lastMemEater = lastMemEater.next; 675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } while (lastMemEater != null); 685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao memEater.confuseCompilerOptimization(memEater); 698ed2e706870c05411f0836b291263689aa1c6959Mark Mendell InstanceMemEater.hook = null; 70ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes return InstanceMemEater.sawOome; 715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public static void main(String[] args) { 74a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier if (triggerReflectionOOM()) { 75a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier System.out.println("Test reflection correctly threw"); 76a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } 77a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier 7874d6a8221c11ac4aa72808863db423aca44117f2Nicolas Geoffray if (triggerArrayOOM()) { 79ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes System.out.println("NEW_ARRAY correctly threw OOME"); 80ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes } 81ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes 82ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes if (triggerInstanceOOM()) { 83ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes System.out.println("NEW_INSTANCE correctly threw OOME"); 84ff9af2220a9d0ef8e7c7f34448c6cfae144e7509Elliott Hughes } 855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 86a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier 87a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier static Object[] holder; 88a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier 89a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier public static void blowup() throws Exception { 90a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier int size = 32 * 1024 * 1024; 91a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier for (int i = 0; i < holder.length; ) { 92a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier try { 93a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier holder[i] = new char[size]; 94a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier i++; 95a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } catch (OutOfMemoryError oome) { 96a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier size = size / 2; 97a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier if (size == 0) { 98a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier break; 99a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } 100a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } 101a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } 102a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier holder[0] = new char[100000]; 103a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } 104a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier 105a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier static boolean triggerReflectionOOM() { 106a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier try { 107a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier Class<?> c = Main.class; 108a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier Method m = c.getMethod("blowup", (Class[]) null); 109a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier holder = new Object[1000000]; 110a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier m.invoke(null); 111a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier holder = null; 112a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier System.out.println("Didn't throw from blowup"); 113a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } catch (OutOfMemoryError e) { 114a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier holder = null; 115a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } catch (InvocationTargetException e) { 116a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier holder = null; 117a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier if (!(e.getCause() instanceof OutOfMemoryError)) { 118a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier System.out.println("InvocationTargetException cause not OOME " + e.getCause()); 119a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier return false; 120a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } 121a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } catch (Exception e) { 122a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier holder = null; 123a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier System.out.println("Unexpected exception " + e); 124a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier return false; 125a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } 126a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier return true; 127a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } 1285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao} 129