#android #memory-leaks #garbage-collection
#Android #утечки памяти #сбор мусора
Вопрос:
В настоящее время я создаю приложение для Android, которое будет запускаться только на планшетах. Одной из функций является отображение списка событий в (пользовательском) диалоговом окне.
В некоторых случаях, когда пользователь подтверждает эти события, в диалоговом окне не собирается мусор, и после открытия диалогового окна несколько раз количество экземпляров диалогового окна, которые хранятся в памяти, увеличивается и увеличивается.
Поскольку приложение должно запускаться в течение длительного времени, я думаю, это приведет к проблемам с памятью.
Итак, я взял дамп памяти и запустил анализатор памяти Eclipse (MAT). У меня никогда раньше не было такой проблемы, и я не слишком знаком с MAT, но вот что я предполагаю:
Я вижу, что есть несколько экземпляров моего диалогового окна и некоторый «внутренний класс» (MyDialog $ 1) все еще там. Для всех других «внутренних классов» (MyDialog $ 2, MyDialog $ 3, …) количество равно 0.
Использование «Объединить кратчайшие пути к корням GC» с опцией «со всеми ссылками» приводит меня к android.view.ViewRoot $ RunQueue $ HandlerAction, поэтому я предполагаю, что каким-то образом сохраняется ссылка на одного из моих слушателей?
Я надеюсь, вы можете сказать мне, правильно ли мое предположение (и мой способ анализа). И, надеюсь, вы можете дать мне решение или подсказку о том, как это решить.
Заранее спасибо, Свен
Комментарии:
1. Как вы создаете диалоговое окно? Когда вы регистрируете своих слушателей?
2. Диалоговое окно является подклассом android.app.Dialog. Диалоговое окно конструктора (контекст Context, тема int) переопределяется. Здесь добавляются элементы графического интерфейса и регистрируются слушатели.
3. Используете ли вы Activity.ShowDialog или DialogFragment для отображения диалогового окна?
4. Диалоговое окно отображается с помощью
new MyDialog(getContext()).show();
Ответ №1:
Я думаю, что вы правы в своем предположении. Слушатель, который является анонимным классом, будет иметь ссылку на окружающий класс. Вы должны отменить регистрацию слушателей, если хотите, чтобы диалоговое окно было уничтожено.
В качестве альтернативы вы можете рассмотреть возможность использования API для управления жизненным циклом диалогового окна. Устаревший Activity.showDialog
и Activity.removeDialog
должен удалять все ссылки на диалоговое окно при его удалении.
В Android 3.0 и выше вы можете использовать DialogFragment
вместо Dialog
, и FragmentManager
он должен обрабатывать его жизненный цикл за вас. См. Руководство разработчика Fragments.