1page.title=Verifying App Behavior on the Android Runtime (ART) 2@jd:body 3 4<div id="qv-wrapper"> 5<div id="qv"> 6<h2>Quickview</h2> 7 <ul> 8 <li>The new Android runtime (ART) is available on some of the newest Android 9 devices, though all of them currently have Dalvik as the default 10 runtime.</li> 11 <li>App developers should make sure their apps are compatible with ART, 12 especially if you use JNI to run native code or if you use certain tools 13 that produce non-standard code (such as some obfuscators).</li> 14 </ul> 15 16 <h2 id="Contents">In this document</h2> 17 <ol> 18 <li><a href="#GC_Migration">Addressing Garbage Collection (GC) Issues</a></li> 19 <li><a href="#JNI_Issues">Preventing JNI Issues</a> 20 <ol> 21 <li><a href="#JNI_and_GC">Checking JNI code for garbage-collection 22 issues</a></li> 23 <li><a href="#Error_Handling">Error handling</a></li> 24 <li><a href="#Object_Model_Changes">Object model changes</a></li> 25 </ol> 26 </li> 27 <li><a href="#Stack_Size">Preventing Stack Size Issues</a></li> 28 <li><a href="#AOT_Fails">Fixing AOT Compilation Issues</a></li> 29 <li><a href="#Reporting_Problems">Reporting Problems</a></li> 30 </ol> 31 <h2>See also</h2> 32 <ol> 33 <li><a href="http://source.android.com/devices/tech/dalvik/art.html">Introducing ART</a></li> 34 <li><a 35href="http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html">Debugging 36Android JNI with CheckJNI</a></li> 37 </ol> 38</div> 39</div> 40 41<p>With Android 4.4, we are beginning to roll out a new Android runtime, 42<strong>ART</strong>. This runtime offers a number of new features that improve 43performance and smoothness of the Android platform and apps. (You can find more 44information about ART's new features in <a 45href="http://source.android.com/devices/tech/dalvik/art.html">Introducing 46ART</a>.)</p> 47 48<p>Currently, ART is available on a number of Android 4.4 devices, such as the 49Nexus 4, Nexus 5, Nexus 7, and Google Play edition devices. 50At this time, all devices still use Dalvik as the default runtime. We encourage 51you to test your apps for ART compatibility and to take advantage of ART's new 52features. However, for the time being, you should also take care to maintain 53compatibility with Dalvik.</p> 54 55<p>This document lets you know about things to watch for when migrating an 56existing app to be compatible with ART. Most apps should just work when 57running with ART. However, some techniques that work on Dalvik do not work on 58ART. This document discusses some of these issues.</p> 59 60<h2 id="GC_Migration">Addressing Garbage Collection (GC) Issues</h2> 61 62<p>Under Dalvik, apps frequently find it useful to explicitly call {@link 63java.lang.System#gc() System.gc()} to prompt garbage collection (GC). This should be 64far less necessary with ART, particularly if you're invoking garbage collection 65to prevent <a 66href="{@docRoot}tools/debugging/debugging-memory.html#LogMessages"><code>GC_FOR_ALLOC</code></a>-type 67occurrences or to reduce fragmentation. You can verify which runtime is in use 68by calling {@link java.lang.System#getProperty(java.lang.String) 69System.getProperty("java.vm.version")}. If ART is in use, the property's value 70is <code>"2.0.0"</code> or higher.</p> 71 72<p>Furthermore, a compacting garbage collector is under development in the <a 73href="https://source.android.com">Android Open-Source Project (AOSP)</a> to 74improve memory management. Because of this, you should avoid using techniques 75that are incompatible with compacting GC (such as saving pointers to object 76instance data). This is particularly important for apps that make use of the 77Java Native Interface (JNI). For more information, see <a 78href="#JNI_Issues">Preventing JNI Issues</a>.</p> 79 80<h2 id="JNI_Issues">Preventing JNI Issues</h2> 81 82<p>ART's JNI is somewhat stricter than Dalvik's. It is an especially good idea 83to use CheckJNI mode to catch common problems. If your app makes use of C/C++ 84code, you should review the following article:</p> 85 86<p><a 87href="http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html">Debugging 88Android JNI with CheckJNI</a></p> 89 90<h3 id="JNI_and_GC">Checking JNI code for garbage-collection issues</h3> 91 92<p>ART has a compacting garbage collector under development on the 93Android Open Source Project (AOSP). Once the compacting garbage collector is in 94use, objects may be moved in memory. If you use C/C++ code, do not 95perform operations that are incompatible with compacting GC. We have enhanced 96CheckJNI to identify some potential issues (as described in <a 97href="http://android-developers.blogspot.com/2011/11/jni-local-reference-changes-in-ics.html">JNI 98Local Reference Changes in ICS</a>).</p> 99 100<p>One area to watch for in particular is the use of 101<code>Get...ArrayElements()</code> and <code>Release...ArrayElements()</code> 102functions. In runtimes with non-compacting GC, the 103<code>Get...ArrayElements()</code> functions typically return a reference to the 104actual memory backing the array object. If you make a change to one of the 105returned array elements, the array object is itself changed (and the arguments 106to <code>Release...ArrayElements()</code> are usually ignored). However, if 107compacting GC is in use, the <code>Get...ArrayElements()</code> functions may 108return a copy of the memory. If you misuse the reference when compacting GC is 109in use, this can lead to memory corruption or other problems. For example:</p> 110 111<ul> 112 113 <li>If you make any changes to the returned array elements, you must call the 114 appropriate <code>Release...ArrayElements()</code> function when you are done, 115 to make sure the changes you made are correctly copied back to the underlying 116 array object.</li> 117 118 <li>When you release the memory array elements, you must use the appropriate 119 mode, depending on what changes you made: 120 121 <ul> 122 123 <li>If you did not make any changes to the array elements, use 124 <code>JNI_ABORT</code> mode, which releases the memory without copying 125 changes back to the underlying array object.</li> 126 127 <li>If you made changes to the array, and do not need the reference any 128 more, use code <code>0</code> (which updates the array object and frees 129 the copy of the memory).</li> 130 131 <li>If you made changes to the array that you want to commit, and you want 132 to keep the copy of the array, use <code>JNI_COMMIT</code> (which updates 133 the underlying array object and retains the copy).</li> 134 135 </ul> 136 137 </li> 138 139 <li>When you call <code>Release...ArrayElements()</code>, return the same 140 pointer that was originally returned by <code>Get...ArrayElements()</code>. For 141 example, it's not safe to increment the original pointer (to scan through the 142 returned array elements) then pass the incremented pointer to 143 <code>Release...ArrayElements()</code>. Passing this modified pointer can cause 144 the wrong memory to be freed, resulting in memory corruption.</li> 145 146</ul> 147 148<h3 id="Error_Handling">Error handling</h3> 149 150<p>ART's JNI throws errors in a number of cases where Dalvik didn’t. (Once 151again, you can catch many such cases by testing with CheckJNI.)</p> 152 153<p>For example, if <code>RegisterNatives</code> is called with a method that 154does not exist (perhaps because the method was removed by a tool such as 155<strong>ProGuard</strong>), ART now properly throws {@link 156java.lang.NoSuchMethodError}:</p> 157 158<pre class="no-pretty-print"> 15908-12 17:09:41.082 13823 13823 E AndroidRuntime: FATAL EXCEPTION: main 16008-12 17:09:41.082 13823 13823 E AndroidRuntime: java.lang.NoSuchMethodError: 161 no static or non-static method 162 "Lcom/foo/Bar;.native_frob(Ljava/lang/String;)I" 16308-12 17:09:41.082 13823 13823 E AndroidRuntime: 164 at java.lang.Runtime.nativeLoad(Native Method) 16508-12 17:09:41.082 13823 13823 E AndroidRuntime: 166 at java.lang.Runtime.doLoad(Runtime.java:421) 16708-12 17:09:41.082 13823 13823 E AndroidRuntime: 168 at java.lang.Runtime.loadLibrary(Runtime.java:362) 16908-12 17:09:41.082 13823 13823 E AndroidRuntime: 170 at java.lang.System.loadLibrary(System.java:526) 171</pre> 172 173<p>ART also logs an error (visible in logcat) if <code>RegisterNatives</code> is 174called with no methods:</p> 175 176<pre class="no-pretty-print"> 177W/art ( 1234): JNI RegisterNativeMethods: attempt to register 0 native 178methods for <classname> 179</pre> 180 181<p>In addition, the JNI functions <code>GetFieldID()</code> and 182<code>GetStaticFieldID()</code> now properly throw {@link java.lang.NoSuchFieldError} 183instead of simply returning null. Similarly, <code>GetMethodID()</code> and 184<code>GetStaticMethodID()</code> now properly throw {@link java.lang.NoSuchMethodError}. 185This can lead to CheckJNI failures because of the unhandled exceptions or the 186exceptions being thrown to Java callers of native code. This makes it 187particularly important to test ART-compatible apps with CheckJNI mode.</p> 188 189<p>ART expects users of the JNI <code>CallNonvirtual...Method()</code> methods 190(such as <code>CallNonvirtualVoidMethod()</code>) to use the method's declaring 191class, not a subclass, as required by the JNI specification.</p> 192 193<h2 id="Stack_Size">Preventing Stack Size Issues</h2> 194 195<p>Dalvik had separate stacks for native and Java code, with a default Java 196stack size of 32KB and a default native stack size of 1MB. ART has a unified 197stack for better locality. Ordinarily, the ART {@link java.lang.Thread} stack 198size should be approximately the same as for Dalvik. However, if you explicitly 199set stack sizes, you may need to revisit those values for apps running in 200ART.</p> 201 202<ul> 203 204 <li>In Java, review calls to the {@link 205 java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable, 206 java.lang.String, long) Thread} constructor that specify an explicit stack 207 size. For example, you will need to increase the size if {@link 208 java.lang.StackOverflowError} occurs.</li> 209 210 <li>In C/C++, review use of <code>pthread_attr_setstack()</code> and 211 <code>pthread_attr_setstacksize()</code> for threads that also run Java code via 212 JNI. Here is an example of the error logged when an app attempts to call JNI 213 <code>AttachCurrentThread()</code> when the pthread size is too small: 214 215<pre class="no-pretty-print">F/art: art/runtime/thread.cc:435] 216 Attempt to attach a thread with a too-small stack (16384 bytes)</pre> 217 </li> 218 219</ul> 220 221<h2 id="Object_Model_Changes">Object model changes</h2> 222 223<p>Dalvik incorrectly allowed subclasses to override package-private methods. 224ART issues a warning in such cases:</p> 225 226<pre class="no-pretty-print"> 227Before Android 4.1, method void com.foo.Bar.quux() 228would have incorrectly overridden the package-private method in 229com.quux.Quux 230</pre> 231 232<p>If you intend to override a class's method in a different package, declare the 233method as <code>public</code> or <code>protected</code>.</p> 234 235<p>{@link java.lang.Object} now has private fields. Apps that reflect on fields 236in their class hierarchies should be careful not to attempt to look at the 237fields of {@link java.lang.Object}. For example, if you are iterating up a class 238hierarchy as part of a serialization framework, stop when 239 240<pre>Class.getSuperclass() == java.lang.Object.class</pre> 241 242instead of continuing until the method returns <code>null</code>.</p> 243 244<p>Proxy {@link 245java.lang.reflect.InvocationHandler#invoke(java.lang.Object,java.lang.reflect.Method,java.lang.Object[]) 246InvocationHandler.invoke()} now receives <code>null</code> if there are no 247arguments instead of an empty array. This behavior was documented previously but 248not correctly handled in Dalvik. Previous versions of <a 249href="https://code.google.com/p/mockito/">Mockito</a> have difficulties with 250this, so use an updated Mockito version when testing with ART.</p> 251 252<h2 id="AOT_Fails">Fixing AOT Compilation Issues</h2> 253 254<p>ART's Ahead-Of-Time (AOT) Java compilation should work for all standard Java 255code. Compilation is performed by ART's 256<code>dex2oat</code> tool; if you encounter any issues related to 257<code>dex2oat</code> at install time, let us know (see <a 258href="#Reporting_Problems">Reporting Problems</a>) so we can fix them as quickly 259as possible. A couple of issues to note:</p> 260 261<ul> 262 263 <li>ART does tighter bytecode verification at install time than Dalvik does. 264 Code produced by the Android build tools should be fine. However, some 265 post-processing tools (especially tools that perform obfuscation) may produce 266 invalid files that are tolerated by Dalvik but rejected by ART. We have been 267 working with tool vendors to find and fix such issues. In many cases, getting 268 the latest versions of your tools and regenerating the DEX files can fix these 269 problems.</li> 270 271 <li>Some typical problems that are flagged by the ART verifier include: 272 <ul> 273 <li>invalid control flow</li> 274 <li>unbalanced <code>moniterenter</code>/<code>moniterexit</code></li> 275 <li>0-length parameter type list size</li> 276 </ul> 277 </li> 278 279 <li>Some apps have dependencies on the installed <code>.odex</code> file 280 format in <code>/system/framework</code>, <code>/data/dalvik-cache</code>, or 281 in {@link dalvik.system.DexClassLoader}’s optimized output directory. These 282 files are now ELF files and not an extended form of DEX files. While ART tries 283 to follow the same naming and locking rules as Dalvik, apps should not depend 284 on the file format; the format is subject to change without notice.</li> 285 286 287 288<h2 id="Reporting_Problems">Reporting Problems</h2> 289 290<p>If you run into any issues that aren’t due to app JNI issues, report 291them via the Android Open Source Project Issue Tracker at <a 292href="https://code.google.com/p/android/issues/list">https://code.google.com/p/android/issues/list</a>. 293Include an <code>"adb bugreport"</code> and a link to the app in the Google 294Play store if available. Otherwise, if possible, attach an APK that reproduces 295the issue. Note that issues (including attachments) are publicly 296visible.</p> 297