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