androiddexclassloader

Is it still the case that Android never unloads classes?


We have a large app that's always running into the dread method count limit. I've been asked to come up with a way to let it do much more, including supporting plugins. Looking for ways to unload code, I ran across JNI Tips which says

Classes are only unloaded if all classes associated with a ClassLoader can be garbage collected, which is rare but will not be impossible in Android.

This did seem to imply that a plugin can be unloaded if you, say,

  1. use a new DexClassLoader for each .jar file,
  2. only ever refer to the plugin through an interface reference, and
  3. null-out any copies of that interface reference when done.

So, I created a test case:

  1. I created a couple of trivial plugins, using a unique loader for each.
  2. I created a ReferenceQueue<ClassLoader> and created weak references to my two loaders, using that queue; I created/started a thread that loops indefinitely, doing a queue .remove() and reporting.
  3. I similarly created a ReferenceQueue<Class<?>> and created weak references to each plugin's getClass() using the queue; I created/started another thread monitoring the class reference queue.
  4. I create a thousand 1000x1000xARGB_8888 bitmaps to thoroughly force gc.

My monitoring threads seem to work - I saw loader2 get gc-ed when I used loader1 to load both plugins by mistake ;-) - but otherwise my threads stay silent, even on 4.3. Am I maybe missing something obvious in this test case, or is it still the case that the

Dalvik VM doesn't currently unload classes

as Google employee fadden says in Android: When do classes get unloaded by the system?


Solution

  • The Dalvik VM still doesn't unload classes. The JNI Tips page is encouraging good behavior so your app doesn't break if the VM starts unloading classes someday.