Это все еще тот случай, когда Android никогда не выгружает классы?
У нас есть большое приложение, которое всегда сталкивается с пределом количества дредов. Меня попросили придумать способ, позволяющий сделать это намного больше, включая поддержку плагинов. В поисках способов выгрузки кода я наткнулся на советы JNI, в которых говорится
Классы выгружаются только в том случае, если все классы, связанные с ClassLoader, могут быть собраны сборщиком мусора, что редко, но не является невозможным в Android.
Это, похоже, подразумевает, что плагин может быть выгружен, если вы, скажем,
- использовать новый
DexClassLoader
для каждого файла.jar, - только когда-либо ссылаться на плагин через ссылку на интерфейс, и
- обнулите любые копии этой ссылки интерфейса, когда закончите.
Итак, я создал тестовый пример:
- Я создал пару тривиальных плагинов, используя уникальный загрузчик для каждого.
- Я создал
ReferenceQueue<ClassLoader>
и создал слабые ссылки на мои два загрузчика, используя эту очередь; Я создал / запустил поток, который зацикливается бесконечно, делая очередь.remove()
и отчетность. - Я так же создал
ReferenceQueue<Class<?>>
и создал слабые ссылки на каждый плагинgetClass()
используя очередь; Я создал / запустил другой поток, отслеживающий очередь ссылок на классы. - Я создаю тысячу 1000x1000xARGB_8888 растровых изображений, чтобы тщательно форсировать gc.
Кажется, мои потоки мониторинга работают - я видел loader2
получить gc-ed, когда я использовал loader1
загрузить оба плагина по ошибке;-) - но в противном случае мои темы хранят молчание, даже на 4.3. Может быть, я упускаю что-то очевидное в этом тестовом примере, или это все еще
Dalvik VM в настоящее время не выгружает классы
как говорит сотрудник Google fadden в Android: когда классы выгружаются системой?
1 ответ
Dalvik VM до сих пор не выгружает классы. Страница JNI Tips поощряет хорошее поведение, поэтому ваше приложение не сломается, если VM когда-нибудь начнет выгрузку классов.