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