From 220cf297d8754dd93b3af6caccece2a424cf7630 Mon Sep 17 00:00:00 2001 From: Andrew Solovay Date: Tue, 20 May 2014 15:50:13 -0700 Subject: [PATCH] docs: New "Verifying App Behavior on the Android Runtime (ART)" guide. Contains information for developers to make sure their apps work properly with the ART runtime. This doc is staged to: http://asolovay.mtv:9001/guide/practices/verifying-apps-art.html This is intended to be a companion to the newly-expanded "Introducing ART" doc on source.android.com (http://ag/469776), which has general information about ART's new features. Change-Id: I77c6e552cfedb13dee1d256fec15926fffcbbbb3 --- .../guide/practices/verifying-apps-art.jd | 296 ++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 docs/html/guide/practices/verifying-apps-art.jd diff --git a/docs/html/guide/practices/verifying-apps-art.jd b/docs/html/guide/practices/verifying-apps-art.jd new file mode 100644 index 0000000000000..0eedfafbbd939 --- /dev/null +++ b/docs/html/guide/practices/verifying-apps-art.jd @@ -0,0 +1,296 @@ +page.title=Verifying App Behavior on the Android Runtime (ART) +@jd:body + +
+
+

Quickview

+
    +
  • The new Android runtime (ART) is available on some of the newest Android + devices, though all of them currently have Dalvik as the default + runtime.
  • +
  • App developers should make sure their apps are compatible with ART, + especially if you use JNI to run native code or if you use certain tools + that produce non-standard code (such as some obfuscators).
  • +
+ +

In this document

+
    +
  1. Addressing Garbage Collection (GC) Issues
  2. +
  3. Preventing JNI Issues +
      +
    1. Checking JNI code for garbage-collection + issues
    2. +
    3. Error handling
    4. +
    5. Object model changes
    6. +
    +
  4. +
  5. Preventing Stack Size Issues
  6. +
  7. Fixing AOT Compilation Issues
  8. +
  9. Reporting Problems
  10. +
+

See also

+
    +
  1. Introducing ART
  2. +
  3. Debugging +Android JNI with CheckJNI
  4. +
+
+
+ +

With Android 4.4, we are beginning to roll out a new Android runtime, +ART. This runtime offers a number of new features that improve +performance and smoothness of the Android platform and apps. (You can find more +information about ART's new features in Introducing +ART.)

+ +

Currently, ART is available on a number of Android 4.4 devices, such as the +Nexus 4, Nexus 5, Nexus 7, and Google Play edition devices. +At this time, all devices still use Dalvik as the default runtime. We encourage +you to test your apps for ART compatibility and to take advantage of ART's new +features. However, for the time being, you should also take care to maintain +compatibility with Dalvik.

+ +

This document lets you know about things to watch for when migrating an +existing app to be compatible with ART. Most apps should just work when +running with ART. However, some techniques that work on Dalvik do not work on +ART. This document discusses some of these issues.

+ +

Addressing Garbage Collection (GC) Issues

+ +

Under Dalvik, apps frequently find it useful to explicitly call {@link +java.lang.System#gc() System.gc()} to prompt garbage collection (GC). This should be +far less necessary with ART, particularly if you're invoking garbage collection +to prevent GC_FOR_ALLOC-type +occurrences or to reduce fragmentation. You can verify which runtime is in use +by calling {@link java.lang.System#getProperty(java.lang.String) +System.getProperty("dalvik.vm.version")}. If ART is in use, the property's value +is "2.0.0" or higher.

+ +

Furthermore, a compacting garbage collector is under development in the Android Open-Source Project (AOSP) to +improve memory management. Because of this, you should avoid using techniques +that are incompatible with compacting GC (such as saving pointers to object +instance data). This is particularly important for apps that make use of the +Java Native Interface (JNI). For more information, see Preventing JNI Issues.

+ +

Preventing JNI Issues

+ +

ART's JNI is somewhat stricter than Dalvik's. It is an especially good idea +to use CheckJNI mode to catch common problems. If your app makes use of C/C++ +code, you should review the following article:

+ +

Debugging +Android JNI with CheckJNI

+ +

Checking JNI code for garbage-collection issues

+ +

ART has a compacting garbage collector under development on the +Android Open Source Project (AOSP). Once the compacting garbage collector is in +use, objects may be moved in memory. If you use C/C++ code, do not +perform operations that are incompatible with compacting GC. We have enhanced +CheckJNI to identify some potential issues (as described in JNI +Local Reference Changes in ICS).

+ +

One area to watch for in particular is the use of +Get...ArrayElements() and Release...ArrayElements() +functions. In runtimes with non-compacting GC, the +Get...ArrayElements() functions typically return a reference to the +actual memory backing the array object. If you make a change to one of the +returned array elements, the array object is itself changed (and the arguments +to Release...ArrayElements() are usually ignored). However, if +compacting GC is in use, the Get...ArrayElements() functions may +return a copy of the memory. If you misuse the reference when compacting GC is +in use, this can lead to memory corruption or other problems. For example:

+ + + +

Error handling

+ +

ART's JNI throws errors in a number of cases where Dalvik didn’t. (Once +again, you can catch many such cases by testing with CheckJNI.)

+ +

For example, if RegisterNatives is called with a method that +does not exist (perhaps because the method was removed by a tool such as +ProGuard), ART now properly throws {@link +java.lang.NoSuchMethodError}:

+ +
+08-12 17:09:41.082 13823 13823 E AndroidRuntime: FATAL EXCEPTION: main
+08-12 17:09:41.082 13823 13823 E AndroidRuntime: java.lang.NoSuchMethodError:
+    no static or non-static method
+    "Lcom/foo/Bar;.native_frob(Ljava/lang/String;)I"
+08-12 17:09:41.082 13823 13823 E AndroidRuntime:
+    at java.lang.Runtime.nativeLoad(Native Method)
+08-12 17:09:41.082 13823 13823 E AndroidRuntime:
+    at java.lang.Runtime.doLoad(Runtime.java:421)
+08-12 17:09:41.082 13823 13823 E AndroidRuntime:
+    at java.lang.Runtime.loadLibrary(Runtime.java:362)
+08-12 17:09:41.082 13823 13823 E AndroidRuntime:
+    at java.lang.System.loadLibrary(System.java:526)
+
+ +

ART also logs an error (visible in logcat) if RegisterNatives is +called with no methods:

+ +
+W/art     ( 1234): JNI RegisterNativeMethods: attempt to register 0 native
+methods for <classname>
+
+ +

In addition, the JNI functions GetFieldID() and +GetStaticFieldID() now properly throw {@link java.lang.NoSuchFieldError} +instead of simply returning null. Similarly, GetMethodID() and +GetStaticMethodID() now properly throw {@link java.lang.NoSuchMethodError}. +This can lead to CheckJNI failures because of the unhandled exceptions or the +exceptions being thrown to Java callers of native code. This makes it +particularly important to test ART-compatible apps with CheckJNI mode.

+ +

ART expects users of the JNI CallNonvirtual...Method() methods +(such as CallNonvirtualVoidMethod()) to use the method's declaring +class, not a subclass, as required by the JNI specification.

+ +

Preventing Stack Size Issues

+ +

Dalvik had separate stacks for native and Java code, with a default Java +stack size of 32KB and a default native stack size of 1MB. ART has a unified +stack for better locality. Ordinarily, the ART {@link java.lang.Thread} stack +size should be approximately the same as for Dalvik. However, if you explicitly +set stack sizes, you may need to revisit those values for apps running in +ART.

+ + + +

Object model changes

+ +

Dalvik incorrectly allowed subclasses to override package-private methods. +ART issues a warning in such cases:

+ +
+Before Android 4.1, method void com.foo.Bar.quux()
+would have incorrectly overridden the package-private method in
+com.quux.Quux
+
+ +

If you intend to override a class's method in a different package, declare the +method as public or protected.

+ +

{@link java.lang.Object} now has private fields. Apps that reflect on fields +in their class hierarchies should be careful not to attempt to look at the +fields of {@link java.lang.Object}. For example, if you are iterating up a class +hierarchy as part of a serialization framework, stop when + +

Class.getSuperclass() == java.lang.Object.class
+ +instead of continuing until the method returns null.

+ +

Proxy {@link +java.lang.reflect.InvocationHandler#invoke(java.lang.Object,java.lang.reflect.Method,java.lang.Object[]) +InvocationHandler.invoke()} now receives null if there are no +arguments instead of an empty array. This behavior was documented previously but +not correctly handled in Dalvik. Previous versions of Mockito have difficulties with +this, so use an updated Mockito version when testing with ART.

+ +

Fixing AOT Compilation Issues

+ +

ART's Ahead-Of-Time (AOT) Java compilation should work for all standard Java +code. Compilation is performed by ART's +dex2oat tool; if you encounter any issues related to +dex2oat at install time, let us know (see Reporting Problems) so we can fix them as quickly +as possible. A couple of issues to note:

+ +