1 /* 2 * Copyright (C) 2007 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 package dalvik.system; 18 19 import java.util.HashMap; 20 import java.util.Map; 21 22 /** 23 * Provides an interface to VM-global, Dalvik-specific features. 24 * An application cannot create its own Runtime instance, and must obtain 25 * one from the getRuntime method. 26 * 27 * @hide 28 */ 29 public final class VMRuntime { 30 31 /** 32 * Holds the VMRuntime singleton. 33 */ 34 private static final VMRuntime THE_ONE = new VMRuntime(); 35 36 private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP 37 = new HashMap<String, String>(); 38 static { 39 ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm"); 40 ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm"); 41 ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips"); 42 ABI_TO_INSTRUCTION_SET_MAP.put("mips64", "mips64"); 43 ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86"); 44 ABI_TO_INSTRUCTION_SET_MAP.put("x86_64", "x86_64"); 45 ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a", "arm64"); 46 } 47 48 private int targetSdkVersion; 49 50 /** 51 * Prevents this class from being instantiated. 52 */ 53 private VMRuntime() { 54 } 55 56 /** 57 * Returns the object that represents the VM instance's Dalvik-specific 58 * runtime environment. 59 * 60 * @return the runtime object 61 */ 62 public static VMRuntime getRuntime() { 63 return THE_ONE; 64 } 65 66 /** 67 * Returns a copy of the VM's command-line property settings. 68 * These are in the form "name=value" rather than "-Dname=value". 69 */ 70 public native String[] properties(); 71 72 /** 73 * Returns the VM's boot class path. 74 */ 75 public native String bootClassPath(); 76 77 /** 78 * Returns the VM's class path. 79 */ 80 public native String classPath(); 81 82 /** 83 * Returns the VM's version. 84 */ 85 public native String vmVersion(); 86 87 /** 88 * Returns the name of the shared library providing the VM implementation. 89 */ 90 public native String vmLibrary(); 91 92 /** 93 * Returns the VM's instruction set. 94 */ 95 public native String vmInstructionSet(); 96 97 /** 98 * Returns whether the VM is running in 64-bit mode. 99 */ 100 public native boolean is64Bit(); 101 102 /** 103 * Returns whether the VM is running with JNI checking enabled. 104 */ 105 public native boolean isCheckJniEnabled(); 106 107 /** 108 * Gets the current ideal heap utilization, represented as a number 109 * between zero and one. After a GC happens, the Dalvik heap may 110 * be resized so that (size of live objects) / (size of heap) is 111 * equal to this number. 112 * 113 * @return the current ideal heap utilization 114 */ 115 public native float getTargetHeapUtilization(); 116 117 /** 118 * Sets the current ideal heap utilization, represented as a number 119 * between zero and one. After a GC happens, the Dalvik heap may 120 * be resized so that (size of live objects) / (size of heap) is 121 * equal to this number. 122 * 123 * <p>This is only a hint to the garbage collector and may be ignored. 124 * 125 * @param newTarget the new suggested ideal heap utilization. 126 * This value may be adjusted internally. 127 * @return the previous ideal heap utilization 128 * @throws IllegalArgumentException if newTarget is <= 0.0 or >= 1.0 129 */ 130 public float setTargetHeapUtilization(float newTarget) { 131 if (newTarget <= 0.0f || newTarget >= 1.0f) { 132 throw new IllegalArgumentException(newTarget + 133 " out of range (0,1)"); 134 } 135 /* Synchronize to make sure that only one thread gets 136 * a given "old" value if both update at the same time. 137 * Allows for reliable save-and-restore semantics. 138 */ 139 synchronized (this) { 140 float oldTarget = getTargetHeapUtilization(); 141 nativeSetTargetHeapUtilization(newTarget); 142 return oldTarget; 143 } 144 } 145 146 /** 147 * Sets the target SDK version. Should only be called before the 148 * app starts to run, because it may change the VM's behavior in 149 * dangerous ways. Use 0 to mean "current" (since callers won't 150 * necessarily know the actual current SDK version, and the 151 * allocated version numbers start at 1), and 10000 to mean 152 * CUR_DEVELOPMENT. 153 */ 154 public synchronized void setTargetSdkVersion(int targetSdkVersion) { 155 this.targetSdkVersion = targetSdkVersion; 156 setTargetSdkVersionNative(this.targetSdkVersion); 157 } 158 159 /** 160 * Gets the target SDK version. See {@link #setTargetSdkVersion} for 161 * special values. 162 */ 163 public synchronized int getTargetSdkVersion() { 164 return targetSdkVersion; 165 } 166 167 private native void setTargetSdkVersionNative(int targetSdkVersion); 168 169 /** 170 * This method exists for binary compatibility. It was part of a 171 * heap sizing API which was removed in Android 3.0 (Honeycomb). 172 */ 173 @Deprecated 174 public long getMinimumHeapSize() { 175 return 0; 176 } 177 178 /** 179 * This method exists for binary compatibility. It was part of a 180 * heap sizing API which was removed in Android 3.0 (Honeycomb). 181 */ 182 @Deprecated 183 public long setMinimumHeapSize(long size) { 184 return 0; 185 } 186 187 /** 188 * This method exists for binary compatibility. It used to 189 * perform a garbage collection that cleared SoftReferences. 190 */ 191 @Deprecated 192 public void gcSoftReferences() {} 193 194 /** 195 * This method exists for binary compatibility. It is equivalent 196 * to {@link System#runFinalization}. 197 */ 198 @Deprecated 199 public void runFinalizationSync() { 200 System.runFinalization(); 201 } 202 203 /** 204 * Implements setTargetHeapUtilization(). 205 * 206 * @param newTarget the new suggested ideal heap utilization. 207 * This value may be adjusted internally. 208 */ 209 private native void nativeSetTargetHeapUtilization(float newTarget); 210 211 /** 212 * This method exists for binary compatibility. It was part of 213 * the external allocation API which was removed in Android 3.0 (Honeycomb). 214 */ 215 @Deprecated 216 public boolean trackExternalAllocation(long size) { 217 return true; 218 } 219 220 /** 221 * This method exists for binary compatibility. It was part of 222 * the external allocation API which was removed in Android 3.0 (Honeycomb). 223 */ 224 @Deprecated 225 public void trackExternalFree(long size) {} 226 227 /** 228 * This method exists for binary compatibility. It was part of 229 * the external allocation API which was removed in Android 3.0 (Honeycomb). 230 */ 231 @Deprecated 232 public long getExternalBytesAllocated() { 233 return 0; 234 } 235 236 /** 237 * Tells the VM to enable the JIT compiler. If the VM does not have a JIT 238 * implementation, calling this method should have no effect. 239 */ 240 public native void startJitCompilation(); 241 242 /** 243 * Tells the VM to disable the JIT compiler. If the VM does not have a JIT 244 * implementation, calling this method should have no effect. 245 */ 246 public native void disableJitCompilation(); 247 248 /** 249 * Returns an array allocated in an area of the Java heap where it will never be moved. 250 * This is used to implement native allocations on the Java heap, such as DirectByteBuffers 251 * and Bitmaps. 252 */ 253 public native Object newNonMovableArray(Class<?> componentType, int length); 254 255 /** 256 * Returns an array of at least minLength, but potentially larger. The increased size comes from 257 * avoiding any padding after the array. The amount of padding varies depending on the 258 * componentType and the memory allocator implementation. 259 */ 260 public native Object newUnpaddedArray(Class<?> componentType, int minLength); 261 262 /** 263 * Returns the address of array[0]. This differs from using JNI in that JNI might lie and 264 * give you the address of a copy of the array when in forcecopy mode. 265 */ 266 public native long addressOf(Object array); 267 268 /** 269 * Removes any growth limits, allowing the application to allocate 270 * up to the maximum heap size. 271 */ 272 public native void clearGrowthLimit(); 273 274 /** 275 * Returns true if either a Java debugger or native debugger is active. 276 */ 277 public native boolean isDebuggerActive(); 278 279 /** 280 * Registers a native allocation so that the heap knows about it and performs GC as required. 281 * If the number of native allocated bytes exceeds the native allocation watermark, the 282 * function requests a concurrent GC. If the native bytes allocated exceeds a second higher 283 * watermark, it is determined that the application is registering native allocations at an 284 * unusually high rate and a GC is performed inside of the function to prevent memory usage 285 * from excessively increasing. 286 */ 287 public native void registerNativeAllocation(int bytes); 288 289 /** 290 * Registers a native free by reducing the number of native bytes accounted for. 291 */ 292 public native void registerNativeFree(int bytes); 293 294 public native void trimHeap(); 295 public native void concurrentGC(); 296 297 /** 298 * Let the heap know of the new process state. This can change allocation and garbage collection 299 * behavior regarding trimming and compaction. 300 */ 301 public native void updateProcessState(int state); 302 303 /** 304 * Fill in dex caches with classes, fields, and methods that are 305 * already loaded. Typically used after Zygote preloading. 306 */ 307 public native void preloadDexCaches(); 308 309 /** 310 * Register application info 311 */ 312 public static native void registerAppInfo(String appDir, String processName, String pkgname); 313 314 /** 315 * Returns the runtime instruction set corresponding to a given ABI. Multiple 316 * compatible ABIs might map to the same instruction set. For example 317 * {@code armeabi-v7a} and {@code armeabi} might map to the instruction set {@code arm}. 318 * 319 * This influences the compilation of the applications classes. 320 */ 321 public static String getInstructionSet(String abi) { 322 final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi); 323 if (instructionSet == null) { 324 throw new IllegalArgumentException("Unsupported ABI: " + abi); 325 } 326 327 return instructionSet; 328 } 329 330 public static boolean is64BitInstructionSet(String instructionSet) { 331 return "arm64".equals(instructionSet) || 332 "x86_64".equals(instructionSet) || 333 "mips64".equals(instructionSet); 334 } 335 336 public static boolean is64BitAbi(String abi) { 337 return is64BitInstructionSet(getInstructionSet(abi)); 338 } 339 340 /** 341 * Return false if the boot class path for the given instruction 342 * set mapped from disk storage, versus being interpretted from 343 * dirty pages in memory. 344 */ 345 public static native boolean isBootClassPathOnDisk(String instructionSet); 346 347 /** 348 * Returns the instruction set of the current runtime. 349 */ 350 public static native String getCurrentInstructionSet(); 351 352 } 353