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