BottomSheetDialogFragment утечка памяти (используйте утечку информации) - PullRequest
0 голосов
/ 19 февраля 2019

Я обнаружил утечку памяти в моем PopupDialog, но я не знаю почему.

Итак, я закомментировал все переопределенные методы, но у меня все еще есть утечка.

BottomSheetDialog

class PopupDialog : BottomSheetDialogFragment() {

    // Annotated all methods and variable.

}

Активность

fun showPopupDialog() = 
    PopupDialog().show(supportFragmentManager, "DialogTag.POPUP_DIALOG")

течь в канале

enter image description here

1 Ответ

0 голосов
/ 12 марта 2019

Если вы нажмете на узел Message.obj (excluded), вы увидите следующее сообщение.

Исключено из-за совпадения правил поля android.os.Message # obj, поскольку поток, ожидающий в очереди блокировки, утечетпоследний удаленный объект как локальная ссылка стека.Поэтому, когда HandlerThread становится бездействующим, он сохраняет локальную ссылку на последнее полученное сообщение.Это сообщение затем перерабатывается и может быть использовано снова.Пока все сообщения перерабатываются после использования, это не будет проблемой, потому что эти ссылки очищаются при переработке.Однако в диалоговых окнах создаются шаблоны экземпляров сообщений, которые необходимо скопировать, когда сообщение необходимо отправить.Эти шаблоны сообщений содержат ссылки на прослушиватели диалогов, что, скорее всего, приводит к тому, что ссылка каким-либо образом сохраняется на действии.Диалоги никогда не перезаписывают свой шаблон сообщения, при условии, что эти экземпляры сообщения получат GCed, когда диалог GCed.Сочетание этих двух вещей создает высокий потенциал для утечек памяти, как только вы используете диалоги.Эти утечки памяти могут быть временными, но некоторые потоки обработчиков спят в течение длительного времени.Чтобы это исправить, вы можете время от времени публиковать пустые сообщения в потоках неработающего обработчика.Это будет непросто, потому что вы не можете получить доступ ко всем потокам обработчиков, но широко используемая библиотека должна рассмотреть возможность сделать это для своих собственных потоков обработчиков.Было показано, что эта утечка происходит как в Dalvik, так и в ART.

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

Обработчик, созданный в главном потоке, будет присоединен к петлителю основного потока.

Таким образом, вы могли бы сделать что-то подобное existingHander.post {}или для создания нового обработчика вы можете сделать это Handler(Looper.getMainLooper()).post {}

Источник: https://github.com/square/leakcanary/blob/master/leakcanary-android/src/main/java/com/squareup/leakcanary/AndroidExcludedRefs.java#L128

...