website/docs/technical_details/interdex.md
The Interdex Pass addresses the problem that the ordering of classes inside dexes and their distribution between dexes (if the application has multiple dexes) does not correspond to the order that they are accessed with during runtime if we use the normal compilation tool chain.
Consider a dex with classes c0, c1, c2, ... . Let's assume the order in which they are accessed during runtime is c0, c1, c2, ... . The actual layout in the bytecode section might be c1000, c291, c3, c705, ..., c0,..., c1 and so on
And of course the same issue happens if there are multiple dexes, with the additional problem that classes might be in different dexes too.
Reordering classes to be in the same order as they are accessed at runtime has several benefits:
The flow for generating profiling data is:
Note that it is very important that you have compiled the app that you're going to be generating the heap dump with the same settings that you use in your release build, otherwise the class ordering will not reflect reality.
It is equally important that the usage reflects a real-world scenario. Using an overly simplistic test or startup scenario will not generate representative data and will not lead to performance improvements.
Note that if you use proguard for obfuscation or another program to the same end, you'll have to disable those steps for profiling. Obfuscation is not guaranteed to be stable and makes mapping class names from one generated apk to the next difficult.
Connect your device to your computer, so you can execute adb commands. You need to have root on your device to execute the dump heap command. On your computer:
// get the process if of your app
adb shell ps | grep YOUR_APP_NAME | awk '{print $2}' > YOUR_PID ( if you don't have awk, the second value is the pid of your app)
// dump the heap of your app. You WILL NEED ROOT for this step
adb root
adb shell am dumpheap YOUR_PID /data/local/tmp/SOMEDUMP.hprof
// copy the heap to your host computer
adb pull /data/local/tmp/SOMEDUMP.hprof YOUR_DIR_HERE/.
// pass the heap dump to the python script for parsing and printing out the class list // Note that the script needs python 3
redex/tools/hprof/dump_classes_from_hprof.py --hprof YOUR_DIR_HERE/SOMEDUMP.hprof > list_of_classes.txt
If everything worked out, list_of_classes.txt will contain a large number of lines of the form foobar.class You'll note that many of the classes list are actually classes provided by the system and not from your app. This is ok, since the Interdex Pass will ignore any entries for which it cannot find the corresponding classes to in the apk.
Note: you must have enum34 installed for the script to work.
To enable the Interdex pass for you application, add the following to your config file:
There are two flags that can be set to influence the behavior of the Interdex pass
emit_canaries: This flag controls whether each secondary dex has a non-functional canary class added. Defaults to false. Enable this only if you explicitly know that you need it.
static_prune: This flag controls whether Interdex attempts to remove classes that have no references to them from the rest of the set of classes in the pgo list.
adb shell ps | grep YOUR_APP_NAME | awk '{ print $2 }' > YOUR_PID
adb shell dumpsys meminfo YOUR_PID
If you want performance measurements, you'll have to set up a test for app startup and run it on apks with and without the interdex pass applied.