Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2017 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 AAA.Derived;
     18 
     19 public class Main {
     20     public static void main(String[] args) {
     21         try {
     22             // Allocate memory for the "AAA.Derived" class name before eating memory.
     23             String aaaDerivedName = "AAA.Derived";
     24             System.out.println("Eating all memory.");
     25             // Resolve VMClassLoader before eating all the memory since we can not fail
     26             // initializtaion of boot classpath classes.
     27             Class.forName("java.lang.VMClassLoader");
     28             Object memory = eatAllMemory();
     29 
     30             // This test assumes that Derived is not yet resolved. In some configurations
     31             // (notably interp-ac), Derived is already resolved by verifying Main at run
     32             // time. Therefore we cannot assume that we get a certain `value` and need to
     33             // simply check for consistency, i.e. `value == another_value`.
     34             int value = 0;
     35             try {
     36                 // If the ArtMethod* is erroneously left in the DexCache, this
     37                 // shall succeed despite the class Derived being unresolved so
     38                 // far. Otherwise, we shall throw OOME trying to resolve it.
     39                 value = Derived.foo();
     40             } catch (OutOfMemoryError e) {
     41                 value = -1;
     42             }
     43             int another_value = 0;
     44             try {
     45                 // For comparison, try to resolve the class Derived directly.
     46                 Class.forName(aaaDerivedName, false, Main.class.getClassLoader());
     47                 another_value = 42;
     48             } catch (OutOfMemoryError e) {
     49                 another_value = -1;
     50             }
     51             boolean memoryWasAllocated = (memory != null);
     52             memory = null;
     53             System.out.println("memoryWasAllocated = " + memoryWasAllocated);
     54             System.out.println("match: " + (value == another_value));
     55             if (value != another_value || (value != -1 && value != 42)) {
     56                 // Mismatch or unexpected value, print additional debugging information.
     57                 System.out.println("value: " + value);
     58                 System.out.println("another_value: " + another_value);
     59             }
     60         } catch (Throwable t) {
     61             t.printStackTrace(System.out);
     62         }
     63     }
     64 
     65     public static Object eatAllMemory() {
     66       Object[] result = null;
     67       int size = 1000000;
     68       while (result == null && size != 0) {
     69           try {
     70               result = new Object[size];
     71           } catch (OutOfMemoryError oome) {
     72               size /= 2;
     73           }
     74       }
     75       if (result != null) {
     76           int index = 0;
     77           while (index != result.length && size != 0) {
     78               try {
     79                   result[index] = new byte[size];
     80                   ++index;
     81               } catch (OutOfMemoryError oome) {
     82                   size /= 2;
     83               }
     84           }
     85       }
     86       return result;
     87   }
     88 }
     89