Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Infamous 64K

The Infamous 64K

My take researching our troubled Android application that hit the limit earlier than our expectation.

This deck mainly explains two issue, Android number of method exceeds issue and LinearAlloc issue.

I created this deck to explain and summarise the technical aspect of this problem to the team with some potential remedies. This is by no mean definitive information. Those who stumble upon this issue and would like to tackle it, should use this deck in order to find out more up to date information on the issue.

One thing I didn't cover is how you count number of methods for each package. Details information can be found on my blog http://poohdish.ghost.io/managing-android-methods-limitation/

Poohdish Rattanavijai

August 26, 2014
Tweet

More Decks by Poohdish Rattanavijai

Other Decks in Programming

Transcript

  1. What exactly is 64K • It is in fact 65,535.

    • Number of methods that can be referenced in one dex file. • It's baked into Dalvik instruction. invoke-kind {vC, vD, vE, vF, vG}, meth@BBBB B: method reference index (16 bits) • This limitation is in every version of Android to date.
  2. In English? Android only allow usage of 65,535 methods. Practising

    aside, you may create unused methods and it will not be count toward the total.
  3. Are you telling me you use that many methods in

    a simple app? Nop. This total methods count all the referenced methods from various places such as your app, libraries, or even Android framework.
  4. So there must be solution out there then? Well, there

    are some. 1. Multiple dex files 2. Shrink using ProGuard 3. Repackage using Jar Jar Links
  5. Multiple dex files Split dex file into primary and secondary

    dex file at build time. • Should work in the long run. • Required to manually loading every class to use. • Manual filtering of which should be on primary dex class. • More susceptible to run time error rather than find it at compilation. • Add load time to the start of the app.
  6. Multiple dex files (cont.) ClassLoader cl = getClassLoader(); ApplicationInfo ai

    = getApplicationInfo(); String nativeLibraryDir = null; if (Build.VERSION.SDK_INT > 8) { nativeLibraryDir = ai.nativeLibraryDir; } else { nativeLibraryDir = "/data/data/" + ai.packageName + "/lib/"; } DexClassLoader dcl = new DexClassLoader(dexFile.getAbsolutePath(), dexOpt.getAbsolutePath(), nativeLibraryDir, cl.getParent()); try { Field f = ClassLoader.class.getDeclaredField("parent"); f.setAccessible(true); f.set(cl, dcl); } catch (Exception e) { throw new RuntimeException(e); }
  7. Shrink using ProGuard Removing unused methods when building the APK

    file. • Required time up front to configure to ensure referenced methods is not removed incorrectly. • Add significant build time for developing/debugging. • Does not entirely remove the limitation • Make the code harder to reengineer.
  8. Repackage using Jar Jar Links Using Jar Jar Links to

    repackage libraries into our app. • Removing libraries can result in difficulty when updating said libraries. • Need to specify all the packages to repackage. • Only applicable on jar files.
  9. There's also LinearAlloc buffer issue in Dalvik on old Android

    devices This is due some old Android devices only having 5MB method allocation buffer. Current devices usually ship with 8-16MB buffer. Facebook sort of fix it in an insane way.
  10. Findings • Custom Class Loading in Dalvik, http://android- developers.blogspot.co.il/2011/07/custom-class-loading-in- dalvik.html

    • ProGuard, http://developer.android.com/tools/help/ proguard.html • Jar Jar Links, https://code.google.com/p/jarjar/ • Facebook is insane, https://www.facebook.com/notes/ facebook-engineering/under-the-hood-dalvik-patch-for- facebook-for-android/10151345597798920