Main.java revision aec9c8f142ad839883ae3de7383456a08823a282
1/*
2 * Copyright (C) 2008 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
17import java.util.Arrays;
18import java.util.LinkedList;
19
20/**
21 * Exercise the construction and throwing of OutOfMemoryError.
22 */
23public class Main {
24    public static void main(String args[]) {
25        System.out.println("tests beginning");
26        testHugeArray();
27        testOomeLarge();
28        testOomeSmall();
29        System.out.println("tests succeeded");
30    }
31
32    private static void testHugeArray() {
33        try {
34            final int COUNT = 32768*32768 + 4;
35            int[] tooBig = new int[COUNT];
36
37            Arrays.fill(tooBig, 0xdd);
38        } catch (OutOfMemoryError oom) {
39            System.out.println("Got expected huge-array OOM");
40        }
41    }
42
43    private static void testOomeLarge() {
44        System.out.println("testOomeLarge beginning");
45
46        Boolean sawEx = false;
47        byte[] a;
48
49        try {
50            // Just shy of the typical max heap size so that it will actually
51            // try to allocate it instead of short-circuiting.
52            a = new byte[(int) Runtime.getRuntime().maxMemory() - 32];
53        } catch (OutOfMemoryError oom) {
54            //Log.i(TAG, "HeapTest/OomeLarge caught " + oom);
55            sawEx = true;
56        }
57
58        if (!sawEx) {
59            throw new RuntimeException("Test failed: " +
60                    "OutOfMemoryError not thrown");
61        }
62
63        System.out.println("testOomeLarge succeeded");
64    }
65
66    /* Do this in another method so that the GC has a chance of freeing the
67     * list afterwards.  Even if we null out list when we're done, the conservative
68     * GC may see a stale pointer to it in a register.
69     */
70    private static boolean testOomeSmallInternal() {
71        final int LINK_SIZE = 6 * 4; // estimated size of a LinkedList's node
72
73        LinkedList<Object> list = new LinkedList<Object>();
74
75        /* Allocate progressively smaller objects to fill up the entire heap.
76         */
77        int objSize = 1 * 1024 * 1024;
78        while (objSize >= LINK_SIZE) {
79            boolean sawEx = false;
80            try {
81                for (int i = 0; i < Runtime.getRuntime().maxMemory() / objSize; i++) {
82                    list.add((Object)new byte[objSize]);
83                }
84            } catch (OutOfMemoryError oom) {
85                sawEx = true;
86            }
87
88            if (!sawEx) {
89                return false;
90            }
91
92            objSize = (objSize * 4) / 5;
93        }
94
95        return true;
96    }
97
98    private static void testOomeSmall() {
99        System.out.println("testOomeSmall beginning");
100        if (!testOomeSmallInternal()) {
101            /* Can't reliably throw this from inside the internal function, because
102             * we may not be able to allocate the RuntimeException.
103             */
104            throw new RuntimeException("Test failed: " +
105                    "OutOfMemoryError not thrown while filling heap");
106        }
107        System.out.println("testOomeSmall succeeded");
108    }
109}
110