1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFaddenimport java.util.Arrays;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.LinkedList;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Exercise the construction and throwing of OutOfMemoryError.
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class Main {
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static void main(String args[]) {
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.out.println("tests beginning");
26f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden        testHugeArray();
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        testOomeLarge();
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        testOomeSmall();
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.out.println("tests succeeded");
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden    private static void testHugeArray() {
33f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden        try {
34f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden            final int COUNT = 32768*32768 + 4;
35f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden            int[] tooBig = new int[COUNT];
36f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden
37f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden            Arrays.fill(tooBig, 0xdd);
38f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden        } catch (OutOfMemoryError oom) {
39f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden            System.out.println("Got expected huge-array OOM");
40f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden        }
41f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden    }
42f6b6389dc3096c361d86e664b5db7292acb113b0Andy McFadden
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static void testOomeLarge() {
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.out.println("testOomeLarge beginning");
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Boolean sawEx = false;
47aec9c8f142ad839883ae3de7383456a08823a282Elliott Hughes        byte[] a;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
50aec9c8f142ad839883ae3de7383456a08823a282Elliott Hughes            // Just shy of the typical max heap size so that it will actually
51aec9c8f142ad839883ae3de7383456a08823a282Elliott Hughes            // try to allocate it instead of short-circuiting.
52aec9c8f142ad839883ae3de7383456a08823a282Elliott Hughes            a = new byte[(int) Runtime.getRuntime().maxMemory() - 32];
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (OutOfMemoryError oom) {
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //Log.i(TAG, "HeapTest/OomeLarge caught " + oom);
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sawEx = true;
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!sawEx) {
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("Test failed: " +
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "OutOfMemoryError not thrown");
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.out.println("testOomeLarge succeeded");
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* Do this in another method so that the GC has a chance of freeing the
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * list afterwards.  Even if we null out list when we're done, the conservative
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * GC may see a stale pointer to it in a register.
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static boolean testOomeSmallInternal() {
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        final int LINK_SIZE = 6 * 4; // estimated size of a LinkedList's node
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LinkedList<Object> list = new LinkedList<Object>();
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* Allocate progressively smaller objects to fill up the entire heap.
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int objSize = 1 * 1024 * 1024;
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (objSize >= LINK_SIZE) {
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            boolean sawEx = false;
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            try {
81aec9c8f142ad839883ae3de7383456a08823a282Elliott Hughes                for (int i = 0; i < Runtime.getRuntime().maxMemory() / objSize; i++) {
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    list.add((Object)new byte[objSize]);
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } catch (OutOfMemoryError oom) {
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sawEx = true;
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!sawEx) {
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return false;
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            objSize = (objSize * 4) / 5;
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static void testOomeSmall() {
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.out.println("testOomeSmall beginning");
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!testOomeSmallInternal()) {
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* Can't reliably throw this from inside the internal function, because
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * we may not be able to allocate the RuntimeException.
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("Test failed: " +
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "OutOfMemoryError not thrown while filling heap");
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.out.println("testOomeSmall succeeded");
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
110