xref: /aosp_15_r20/art/test/1000-non-moving-space-stress/src-art/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2018 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 
17 import dalvik.system.VMRuntime;
18 import java.lang.ref.Reference;  // For reachabilityFence.
19 import java.util.ArrayList;
20 
21 public class Main {
22   private static final boolean SHOULD_PRINT = false;  // True causes failure.
23 
main(String[] args)24   public static void main(String[] args) throws Exception {
25     VMRuntime runtime = VMRuntime.getRuntime();
26 
27     try {
28       int N = 1024 * 1024;
29       int S = 512;
30       for (int n = 0; n < N; ++n) {
31         // Allocate unreachable objects.
32         $noinline$Alloc(runtime);
33         // Allocate an object with a substantial size to increase memory
34         // pressure and eventually trigger non-explicit garbage collection
35         // (explicit garbage collections triggered by java.lang.Runtime.gc()
36         // are always full GCs). Upon garbage collection, the objects
37         // allocated in $noinline$Alloc used to trigger a crash.
38         Object[] moving_array = new Object[S];
39       }
40     } catch (OutOfMemoryError e) {
41       System.out.println("Unexpected OOME");
42     }
43     Runtime.getRuntime().gc();
44     int numAllocs = 0;
45     ArrayList<Object> chunks = new ArrayList<>();
46     try {
47       final int MAX_PLAUSIBLE_ALLOCS = 1024 * 1024;
48       for (numAllocs = 0; numAllocs < MAX_PLAUSIBLE_ALLOCS; ++numAllocs) {
49         chunks.add(runtime.newNonMovableArray(Object.class, 252));  // About 1KB
50       }
51       // If we get here, we've allocated about 1GB of nonmovable memory, which
52       // should be impossible.
53     } catch (OutOfMemoryError e) {
54       chunks.remove(0);  // Give us a little space back.
55       if (((Object[]) (chunks.get(42)))[17] != null) {
56         System.out.println("Bad entry in chunks array");
57       } else {
58         chunks.clear();  // Recover remaining space.
59         if (SHOULD_PRINT) {
60           System.out.println("Successfully allocated " + numAllocs + " non-movable KBs");
61         }
62         System.out.println("passed");
63       }
64       Reference.reachabilityFence(chunks);
65       return;
66     }
67     Reference.reachabilityFence(chunks);
68     System.out.println("Failed to exhaust non-movable space");
69   }
70 
71   // When using the Concurrent Copying (CC) collector (default collector),
72   // this method allocates an object in the non-moving space and an object
73   // in the region space, make the former reference the later, and returns
74   // nothing (so that none of these objects are reachable upon return).
$noinline$Alloc(VMRuntime runtime)75   static void $noinline$Alloc(VMRuntime runtime) {
76     Object[] non_moving_array = (Object[]) runtime.newNonMovableArray(Object.class, 1);
77     // Small object, unlikely to trigger garbage collection.
78     non_moving_array[0] = new Object();
79   }
80 
81 }
82