[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# Android 8.0 ART improvements\n\nThe Android runtime (ART) has been improved significantly in the Android 8.0\nrelease. The list below summarizes enhancements device manufacturers can expect\nin ART.\n\nConcurrent compacting garbage collector\n---------------------------------------\n\n\nAs announced at Google I/O, ART features a new concurrent compacting garbage\ncollector (GC) in Android 8.0. This collector compacts the heap every time GC\nruns and while the app is running, with only one short pause for processing\nthread roots. Here are its benefits:\n\n- GC always compacts the heap: 32% smaller heap sizes on average compared to Android 7.0.\n- Compaction enables thread local bump pointer object allocation: Allocations are 70% faster than in Android 7.0.\n- Offers 85% smaller pause times for the H2 benchmark compared to the Android 7.0 GC.\n- Pause times no longer scale with heap size; apps should be able to use large heaps without worrying about jank.\n- GC implementation detail - Read barriers:\n - Read barriers are a small amount of work done for each object field read.\n - These are optimized in the compiler, but might slow down some use cases.\n\nLoop optimizations\n------------------\n\n\nA wide variety of loop optimizations are employed by ART in the Android 8.0\nrelease:\n\n- Bounds check eliminations\n - Static: ranges are proven to be within bounds at compile-time\n - Dynamic: run-time tests ensure loops stay within bounds (deopt otherwise)\n- Induction variable eliminations\n - Remove dead induction\n - Replace induction that is used only after the loop by closed-form expressions\n- Dead code elimination inside the loop-body, removal of whole loops that become dead\n- Strength reduction\n- Loop transformations: reversal, interchanging, splitting, unrolling, unimodular, etc.\n- SIMDization (also called vectorization)\n\n\nThe loop optimizer resides in its own optimization pass in the ART compiler.\nMost loop optimizations are similar to optimizations and simplification\nelsewhere. Challenges arise with some optimizations that rewrite the CFG in a\nmore than usual elaborate way, because most CFG utilities (see nodes.h) focus\non building a CFG, not rewriting one.\n\nClass hierarchy analysis\n------------------------\n\n\nART in Android 8.0 uses Class Hierarchy Analysis (CHA), a compiler optimization\nthat devirtualizes virtual calls into direct calls based on the information\ngenerated by analyzing class hierarchies. Virtual calls are expensive since\nthey are implemented around a vtable lookup, and they take a couple of\ndependent loads. Also virtual calls cannot be inlined.\n\nHere is a summary of related enhancements:\n\n- Dynamic single-implementation method status updating - At the end of class linking time, when vtable has been populated, ART conducts an entry-by-entry comparison to the vtable of the super class.\n- Compiler optimization - The compiler will take advantage of the single-implementation info of a method. If a method A.foo has single-implementation flag set, compiler will devirtualize the virtual call into a direct call, and further try to inline the direct call as a result.\n- Compiled code invalidation - Also at the end of class linking time when single-implementation info is updated, if method A.foo that previously had single-implementation but that status is now invalidated, all compiled code that depends on the assumption that method A.foo has single-implementation needs to have their compiled code invalidated.\n- Deoptimization - For live compiled code that's on stack, deoptimization will be initiated to force the invalidated compiled code into interpreter mode to guarantee correctness. A new mechanism of deoptimization which is a hybrid of synchronous and asynchronous deoptimization will be used.\n\nInline caches in .oat files\n---------------------------\n\n\nART now employs inline caches and optimizes the call sites for which enough\ndata exists. The inline caches feature records additional runtime information\ninto profiles and uses it to add dynamic optimizations to ahead of time compilation.\n\nDexlayout\n---------\n\n\nDexlayout is a library introduced in Android 8.0 to analyze dex files and\nreorder them according to a profile. Dexlayout aims to use runtime profiling\ninformation to reorder sections of the dex file during idle maintenance\ncompilation on device. By grouping together parts of the dex file that are\noften accessed together, programs can have better memory access patterns from\nimproved locality, saving RAM and shortening start up time.\n\n\nSince profile information is currently available only after apps have been run,\ndexlayout is integrated in dex2oat's on-device compilation during idle\nmaintenance.\n\nDex cache removal\n-----------------\n\n\nUp to Android 7.0, the DexCache object owned four large arrays, proportional to\nthe number of certain elements in the DexFile, namely:\n\n- strings (one reference per DexFile::StringId),\n- types (one reference per DexFile::TypeId),\n- methods (one native pointer per DexFile::MethodId),\n- fields (one native pointer per DexFile::FieldId).\n\n\nThese arrays were used for fast retrieval of objects that we previously\nresolved. In Android 8.0, all arrays have been removed except the methods array.\n\nInterpreter performance\n-----------------------\n\n\nInterpreter performance significantly improved in the Android 7.0 release with\nthe introduction of \"mterp\" - an interpreter featuring a core\nfetch/decode/interpret mechanism written in assembly language. Mterp is\nmodelled after the fast Dalvik interpreter, and supports arm, arm64, x86,\nx86_64, mips and mips64. For computational code, Art's mterp is roughly\ncomparable to Dalvik's fast interpreter. However, in some situations it can be\nsignificantly - and even dramatically - slower:\n\n1. Invoke performance.\n2. String manipulation, and other heavy users of methods recognized as intrinsics in Dalvik.\n3. Higher stack memory usage.\n\nAndroid 8.0 addresses these issues.\n\nMore inlining\n-------------\n\n\nSince Android 6.0, ART can inline any call within the same dex files, but could\nonly inline leaf methods from different dex files. There were two reasons for\nthis limitation:\n\n1. Inlining from another dex file requires to use the dex cache of that other dex file, unlike same dex file inlining, which could just re-use the dex cache of the caller. The dex cache is needed in compiled code for a couple of instructions like static calls, string load, or class load.\n2. The stack maps are only encoding a method index within the current dex file.\n\nTo address these limitations, Android 8.0:\n\n1. Removes dex cache access from compiled code (also see section \"Dex cache removal\")\n2. Extends stack map encoding.\n\nSynchronization improvements\n----------------------------\n\n\nThe ART team tuned the MonitorEnter/MonitorExit code paths, and reduced our\nreliance on traditional memory barriers on ARMv8, replacing them with newer\n(acquire/release) instructions where possible.\n\nFaster native methods\n---------------------\n\n\nFaster native calls to the Java Native Interface (JNI) are available using\nthe [`@FastNative`](https://android.googlesource.com/platform/libcore/+/android16-release/dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java) and [`@CriticalNative`](https://android.googlesource.com/platform/libcore/+/android16-release/dalvik/src/main/java/dalvik/annotation/optimization/CriticalNative.java) annotations. These built-in ART runtime\noptimizations speed up JNI transitions and replace the now deprecated\n*!bang JNI* notation. The annotations have no effect on non-native\nmethods and are only available to platform Java Language code on the\n`bootclasspath` (no Play Store updates).\n\n\nThe `@FastNative` annotation supports non-static methods. Use this\nif a method accesses a `jobject` as a parameter or return value.\n\n\nThe `@CriticalNative` annotation provides an even faster way to run\nnative methods, with the following restrictions:\n\n- Methods must be static---no objects for parameters, return values, or an implicit `this`.\n- Only primitive types are passed to the native method.\n- The native method does not use the `JNIEnv` and `jclass` parameters in its function definition.\n- The method must be registered with `RegisterNatives` instead of relying on dynamic JNI linking.\n\n|\n| The `@FastNative` and `@CriticalNative` annotations\n| disable garbage collection while executing a native method. Do not use with\n| long-running methods, including usually-fast, but generally unbounded,\n| methods.\n|\n|\n| Pauses to the garbage collection may cause deadlock. Do not acquire locks\n| during a fast native call if the locks haven't been released locally (i.e.\n| before returning to managed code). This does not apply to regular JNI calls\n| since ART considers the executing native code as suspended.\n\n\n`@FastNative` can improve native method performance up to 3x, and\n`@CriticalNative` up to 5x. For example, a JNI transition measured\non a Nexus 6P device:\n\n| Java Native Interface (JNI) invocation | Execution time (in nanoseconds) |\n|----------------------------------------|---------------------------------|\n| Regular JNI | 115 |\n| *!bang JNI* | 60 |\n| `@FastNative` | 35 |\n| `@CriticalNative` | 25 |"]]