2016-07-26 4 views
6

У меня есть Fragment, у которого есть RecyclerView.Память не освобождается после удаления фрагмента

В этом RecyclerView, я иногда может загружать и отображать изображения (загружается с Glide в ImageView.

Так, когда я открыть Fragment, используемая память может иногда переходить от около 30 МБ около 100 Мб или даже больше.

После Activity, который держит в Fragment закончена, память не освобождает. Она остается такой же, как и раньше.

Glide Я проверил документацию и, видимо, нам не нужно беспокоиться о том, чтобы высвободить Bitmaps в RecyclerView. Это огромная проблема, потому что из-за этого приложение часто выходит из строя из-за OOM.

Как правильно обращаться с освобождением памяти при удалении Fragment?

Edit: одно наблюдение

Другая вещь, которую я заметил, что если я закончу Activity, а затем запустить тот же Activity снова. Память на мгновение отскочит назад, а затем вернется на уровень 100 МБ, что заставляет меня думать, что память очищается перед запуском Fragment.

ответ

4

Сбор мусора иногда является болезненной проблемой в Android. Большинство разработчиков не учитывают эту проблему и продолжают развиваться без какого-либо смысла выделения ресурсов.

Это, конечно, вызовет проблемы с памятью, такие как утечки, OOM и ненужное связывание ресурсов. Нет абсолютно автоматического способа освобождения памяти. Вы не можете, ни при каких обстоятельствах, полагаться исключительно на сборщика мусора

Всякий раз, когда вы передаете фрагмента или на данный вид деятельности OnDestroy() метод, что вы можете и должны сделать, это удалить любую конструкцию, которая не должно быть больше не требуется в приложении. Вы можете сделать следующее:

  1. Избегайте анонимных случаев слушателей. Создавайте слушателей и уничтожайте их, когда они вам больше не нужны.
  2. Установите всех слушателей (их клик, длинный клик и т. Д.) На нуль
  3. Очистить все переменные, массивы. Применить ту же процедуру для всех классов и подклассов, содержащихся внутри деятельности/Фрагмент
  4. Установить переменную в нуль всякий раз, когда вы выполняете какие-либо из предыдущих шагов по этому данному классу (применяется ко всем переменным)

Я в конечном итоге делает было создание интерфейса, как

public interface clearMemory(){ 
    void clearMemory(); 
} 

и его реализации на каждом классе, будь то активность, фрагмент или обычный класс (включает в себя адаптеры, настраиваемые представления и т.д.).

Я бы вызвать метод, когда класс должен был быть разрушен (потому что приложение разрушалась или всякий раз, когда я чувствовал, нужно сделать так. Стараясь не выбрасывайте в нормальном режиме исполнения)

@Override 
public void onDestroy(){ 
    clearMemory(); 
} 

public void clearMemory(){ 
    normalButtonOnClickListener = null; 
    normalButton.setOnClickListener(null); 
    normalButton = null; 
    myCustomClass.clearMemory(); // apply the interface to the class and clear it inside 
    myCustomClass = null; 
    simpleVariable = null; 
    ...   
} 

Реализуя это систематически, управление памятью моих приложений стало проще и компактнее. Затем можно узнать/точно контролировать, как и когда расположена память.

+0

Спасибо, это определенно помогает. Я дам это попробовать завтра (хотя это может занять некоторое время, прежде чем я сделаю это во всем приложении), и я дам вам знать, как это произошло. – Guy

+0

Когда вы сказали очистить все переменные, это означает переменные экземпляра, правильно? Если я создаю переменную в методе onCreate, должен ли я также очистить ее после того, как я перестану ее использовать? – Guy

+0

Да. Все, что вы выделяете, должно/должно быть рассмотрено, как только вы узнаете, что вам больше не понадобится. В качестве метафора: 1) Вы покупаете кусок одноразовой бумаги. Вы пишете на этом листе бумаги несколько фактов о вашем дне 2) Вы будете использовать этот лист бумаги на весь день, но вы знаете, что вам не понадобится бумага навсегда 3) К концу дня вы понимаете бумагу теперь выполнила его цель. 4) Вы отбрасываете бумагу, разрывая ее и бросая в мусорную корзину. Теперь поймите «лист бумаги» как любую переменную, которую вы используете, и ваш «день» в качестве жизненного цикла вашей деятельности. –

1

Это добавление к ответу Рикардо.

Вы можете добавить следующий код, чтобы инициировать сбор мусора в Android:
Runtime.getRuntime().gc();

Примечание: вызов этой функции после того, как вы сделали все локальные переменные нуль. Выполнение этого кода не гарантирует, что система будет собирать мусор в вашем приложении, а просто намекает, что это может быть подходящее время для этого.
Я использовал это во всех своих действиях «onDestroy(), и он всегда работает, когда я этого хочу.
Дайте ему попробовать, это может помочь вам.

+0

Точно. В основном можно вызвать System.gc() для «намека» на систему, и в итоге она будет выполнена для сбора всех объектов без ссылок. Управляемое управление памятью всегда является неотъемлемой частью любого приложения! –

 Смежные вопросы

  • Нет связанных вопросов^_^