xref: /aosp_15_r20/art/test/1000-non-moving-space-stress/src-art/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker import dalvik.system.VMRuntime;
18*795d594fSAndroid Build Coastguard Worker import java.lang.ref.Reference;  // For reachabilityFence.
19*795d594fSAndroid Build Coastguard Worker import java.util.ArrayList;
20*795d594fSAndroid Build Coastguard Worker 
21*795d594fSAndroid Build Coastguard Worker public class Main {
22*795d594fSAndroid Build Coastguard Worker   private static final boolean SHOULD_PRINT = false;  // True causes failure.
23*795d594fSAndroid Build Coastguard Worker 
main(String[] args)24*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) throws Exception {
25*795d594fSAndroid Build Coastguard Worker     VMRuntime runtime = VMRuntime.getRuntime();
26*795d594fSAndroid Build Coastguard Worker 
27*795d594fSAndroid Build Coastguard Worker     try {
28*795d594fSAndroid Build Coastguard Worker       int N = 1024 * 1024;
29*795d594fSAndroid Build Coastguard Worker       int S = 512;
30*795d594fSAndroid Build Coastguard Worker       for (int n = 0; n < N; ++n) {
31*795d594fSAndroid Build Coastguard Worker         // Allocate unreachable objects.
32*795d594fSAndroid Build Coastguard Worker         $noinline$Alloc(runtime);
33*795d594fSAndroid Build Coastguard Worker         // Allocate an object with a substantial size to increase memory
34*795d594fSAndroid Build Coastguard Worker         // pressure and eventually trigger non-explicit garbage collection
35*795d594fSAndroid Build Coastguard Worker         // (explicit garbage collections triggered by java.lang.Runtime.gc()
36*795d594fSAndroid Build Coastguard Worker         // are always full GCs). Upon garbage collection, the objects
37*795d594fSAndroid Build Coastguard Worker         // allocated in $noinline$Alloc used to trigger a crash.
38*795d594fSAndroid Build Coastguard Worker         Object[] moving_array = new Object[S];
39*795d594fSAndroid Build Coastguard Worker       }
40*795d594fSAndroid Build Coastguard Worker     } catch (OutOfMemoryError e) {
41*795d594fSAndroid Build Coastguard Worker       System.out.println("Unexpected OOME");
42*795d594fSAndroid Build Coastguard Worker     }
43*795d594fSAndroid Build Coastguard Worker     Runtime.getRuntime().gc();
44*795d594fSAndroid Build Coastguard Worker     int numAllocs = 0;
45*795d594fSAndroid Build Coastguard Worker     ArrayList<Object> chunks = new ArrayList<>();
46*795d594fSAndroid Build Coastguard Worker     try {
47*795d594fSAndroid Build Coastguard Worker       final int MAX_PLAUSIBLE_ALLOCS = 1024 * 1024;
48*795d594fSAndroid Build Coastguard Worker       for (numAllocs = 0; numAllocs < MAX_PLAUSIBLE_ALLOCS; ++numAllocs) {
49*795d594fSAndroid Build Coastguard Worker         chunks.add(runtime.newNonMovableArray(Object.class, 252));  // About 1KB
50*795d594fSAndroid Build Coastguard Worker       }
51*795d594fSAndroid Build Coastguard Worker       // If we get here, we've allocated about 1GB of nonmovable memory, which
52*795d594fSAndroid Build Coastguard Worker       // should be impossible.
53*795d594fSAndroid Build Coastguard Worker     } catch (OutOfMemoryError e) {
54*795d594fSAndroid Build Coastguard Worker       chunks.remove(0);  // Give us a little space back.
55*795d594fSAndroid Build Coastguard Worker       if (((Object[]) (chunks.get(42)))[17] != null) {
56*795d594fSAndroid Build Coastguard Worker         System.out.println("Bad entry in chunks array");
57*795d594fSAndroid Build Coastguard Worker       } else {
58*795d594fSAndroid Build Coastguard Worker         chunks.clear();  // Recover remaining space.
59*795d594fSAndroid Build Coastguard Worker         if (SHOULD_PRINT) {
60*795d594fSAndroid Build Coastguard Worker           System.out.println("Successfully allocated " + numAllocs + " non-movable KBs");
61*795d594fSAndroid Build Coastguard Worker         }
62*795d594fSAndroid Build Coastguard Worker         System.out.println("passed");
63*795d594fSAndroid Build Coastguard Worker       }
64*795d594fSAndroid Build Coastguard Worker       Reference.reachabilityFence(chunks);
65*795d594fSAndroid Build Coastguard Worker       return;
66*795d594fSAndroid Build Coastguard Worker     }
67*795d594fSAndroid Build Coastguard Worker     Reference.reachabilityFence(chunks);
68*795d594fSAndroid Build Coastguard Worker     System.out.println("Failed to exhaust non-movable space");
69*795d594fSAndroid Build Coastguard Worker   }
70*795d594fSAndroid Build Coastguard Worker 
71*795d594fSAndroid Build Coastguard Worker   // When using the Concurrent Copying (CC) collector (default collector),
72*795d594fSAndroid Build Coastguard Worker   // this method allocates an object in the non-moving space and an object
73*795d594fSAndroid Build Coastguard Worker   // in the region space, make the former reference the later, and returns
74*795d594fSAndroid Build Coastguard Worker   // nothing (so that none of these objects are reachable upon return).
$noinline$Alloc(VMRuntime runtime)75*795d594fSAndroid Build Coastguard Worker   static void $noinline$Alloc(VMRuntime runtime) {
76*795d594fSAndroid Build Coastguard Worker     Object[] non_moving_array = (Object[]) runtime.newNonMovableArray(Object.class, 1);
77*795d594fSAndroid Build Coastguard Worker     // Small object, unlikely to trigger garbage collection.
78*795d594fSAndroid Build Coastguard Worker     non_moving_array[0] = new Object();
79*795d594fSAndroid Build Coastguard Worker   }
80*795d594fSAndroid Build Coastguard Worker 
81*795d594fSAndroid Build Coastguard Worker }
82