blob: b5999b34b3cde5e1a97c115f3b3f651ae183bd5f [file] [log] [blame]
jeffhao5d1ac922011-09-29 17:41:15 -07001/*
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 /* Just shy of the typical max heap size so that it will actually
47 * try to allocate it instead of short-circuiting.
48 *
49 * TODO: stop assuming the VM defaults to 16MB max
50 */
51 final int SIXTEEN_MB = (16 * 1024 * 1024 - 32);
52
53 Boolean sawEx = false;
54 byte a[];
55
56 try {
57 a = new byte[SIXTEEN_MB];
58 } catch (OutOfMemoryError oom) {
59 //Log.i(TAG, "HeapTest/OomeLarge caught " + oom);
60 sawEx = true;
61 }
62
63 if (!sawEx) {
64 throw new RuntimeException("Test failed: " +
65 "OutOfMemoryError not thrown");
66 }
67
68 System.out.println("testOomeLarge succeeded");
69 }
70
71 /* Do this in another method so that the GC has a chance of freeing the
72 * list afterwards. Even if we null out list when we're done, the conservative
73 * GC may see a stale pointer to it in a register.
74 *
75 * TODO: stop assuming the VM defaults to 16MB max
76 */
77 private static boolean testOomeSmallInternal() {
78 final int SIXTEEN_MB = (16 * 1024 * 1024);
79 final int LINK_SIZE = 6 * 4; // estimated size of a LinkedList's node
80
81 LinkedList<Object> list = new LinkedList<Object>();
82
83 /* Allocate progressively smaller objects to fill up the entire heap.
84 */
85 int objSize = 1 * 1024 * 1024;
86 while (objSize >= LINK_SIZE) {
87 boolean sawEx = false;
88 try {
89 for (int i = 0; i < SIXTEEN_MB / objSize; i++) {
90 list.add((Object)new byte[objSize]);
91 }
92 } catch (OutOfMemoryError oom) {
93 sawEx = true;
94 }
95
96 if (!sawEx) {
97 return false;
98 }
99
100 objSize = (objSize * 4) / 5;
101 }
102
103 return true;
104 }
105
106 private static void testOomeSmall() {
107 System.out.println("testOomeSmall beginning");
108 if (!testOomeSmallInternal()) {
109 /* Can't reliably throw this from inside the internal function, because
110 * we may not be able to allocate the RuntimeException.
111 */
112 throw new RuntimeException("Test failed: " +
113 "OutOfMemoryError not thrown while filling heap");
114 }
115 System.out.println("testOomeSmall succeeded");
116 }
117}