1 /* 2 * Copyright (C) 2016 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 import java.util.IdentityHashMap; 17 import dalvik.system.VMRuntime; 18 19 public class Main { main(String[] args)20 public static void main(String[] args) { 21 System.loadLibrary(args[0]); 22 int initialSize = monitorListSize(); 23 IdentityHashMap<Object, Integer> all = new IdentityHashMap(); 24 for (int i = 0; i < 5000; ++i) { 25 Object obj = new Object(); 26 synchronized(obj) { 27 // Should force inflation. 28 all.put(obj, obj.hashCode()); 29 } 30 } 31 // Since monitor deflation is delayed significantly, we believe that even with an intervening 32 // GC, monitors should remain inflated. We allow some slop for unrelated concurrent runtime 33 // actions. 34 int inflatedSize = monitorListSize(); 35 if (inflatedSize >= initialSize + 4000) { 36 System.out.println("Monitor list grew by at least 4000 monitors"); 37 } else { 38 System.out.println("Monitor list did not grow as expected"); 39 } 40 // Encourage monitor deflation. 41 // trim() (Heap::Trim()) deflates only in JANK_IMPERCEPTIBLE state. 42 // Some of this mirrors code in ActivityThread.java. 43 final int DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE = 0; 44 final int DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1; 45 VMRuntime.getRuntime().updateProcessState(DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE); 46 System.gc(); 47 System.runFinalization(); 48 trim(); 49 VMRuntime.getRuntime().updateProcessState(DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE); 50 int finalSize = monitorListSize(); 51 if (finalSize > initialSize + 1000) { 52 System.out.println("Monitor list failed to shrink properly"); 53 } else { 54 System.out.println("Monitor list shrank correctly"); 55 } 56 int j = 0; 57 for (Object obj: all.keySet()) { 58 ++j; 59 if (obj.hashCode() != all.get(obj)) { 60 throw new AssertionError("Failed hashcode test!"); 61 } 62 } 63 System.out.println("Finished first check"); 64 for (Object obj: all.keySet()) { 65 ++j; 66 synchronized(obj) { 67 if (obj.hashCode() != all.get(obj)) { 68 throw new AssertionError("Failed hashcode test!"); 69 } 70 } 71 } 72 System.out.println("Finished second check"); 73 System.out.println("Total checks: " + j); 74 } 75 trim()76 private static native void trim(); 77 monitorListSize()78 private static native int monitorListSize(); 79 } 80