我们有一个大型应用程序,它总是遇到可怕的方法计数限制。我被要求想出一种让它做更多事情的方法,包括支持插件。寻找卸载代码的方法,我遇到了JNI Tips 上面说
仅当与 ClassLoader 关联的所有类都可以被垃圾回收时,类才会被卸载,这在 Android 中很少见,但并非不可能。
这似乎确实意味着如果您说可以卸载插件,
DexClassLoader
为每个 .jar 文件使用一个新的,- 仅通过接口引用引用插件,并且
- 完成后取消该接口引用的任何副本。
所以,我创建了一个测试用例:
- 我创建了几个微不足道的插件,每个插件都使用一个独特的加载器。
- 我使用该队列创建了一个
ReferenceQueue<ClassLoader>
并创建了对我的两个加载器的弱引用;我创建/启动了一个无限循环的线程,进行队列.remove()
和报告。 - 我同样使用队列创建了一个
ReferenceQueue<Class<?>>
并创建了对每个插件的弱引用;getClass()
我创建/启动了另一个监视类引用队列的线程。 - 我创建了一千个 1000x1000xARGB_8888 位图来彻底强制 gc。
我的监控线程似乎可以工作 -当我错误地加载两个插件时,我看到了loader2
gc-ed ;-) - 但否则我的线程保持沉默,即使在 4.3 上也是如此。loader1
我是否可能在这个测试用例中遗漏了一些明显的东西,或者仍然是这样的情况
Dalvik VM 当前不卸载类
正如 Google 员工fadden在Android 中所说:系统何时卸载类?