Eu tenho um conhecimento básico de vazamentos de memória e o que pode causar a eles. É por isso que não entendo se tenho um problema no meu código ou se é um falso positivo. Não sei qual parte do código devo compartilhar, pois o projeto não é pequeno. Mas deixe-me saber nos comentários e adicionarei o código necessário.
Eu uso o componente do arco de navegação e sigo o padrão MVVM. Eu adicionei a biblioteca LeakCanary mais tarde no desenvolvimento do projeto e ela imediatamente começou a me dar avisos sobre instâncias retidas quando eu navegava pelas telas.
O problema ocorre quando adiciono fragmentos à pilha traseira. Com cada fragmento adicionado à pilha traseira, o contador de instâncias retidas aumenta. Quando atinge o valor limite de 5 LeakCanary despeja a pilha e fornece relatório.
Mas se eu clicar no botão Voltar e retornar às telas anteriores, o contador de instâncias retidas diminui e, eventualmente, quando retornadas à 1ª tela, todas as instâncias retidas desaparecem.
Se eu olhar para os relatórios de análise de heap, ele diz que a variável coordenatorLayout, que é uma referência ao CoordinatorLayout
XML, vazou. Se eu remover a variável e todo o seu uso e executar o aplicativo novamente, vejo o mesmo problema, mas agora com outra variável que é uma referência a outra exibição em xml. Tentei remover todas as visualizações e seu uso que o LeakCanary relatou como vazando. Quando ele disse que a TextView
, que é usado apenas para definir um texto onViewCreated
e não usado em nenhum outro lugar, está vazando, comecei a duvidar de que haja um problema no meu código.
Analisei as chamadas do método do ciclo de vida em fragmentos e notei que, quando navego para a nova tela do fragmento anterior, todos os métodos até e inclusive onDestroyView
são chamados, mas não onDestroy
. Quando clico em voltar, onDestroy
é chamado o fragmento que estava no topo da pilha traseira e o contador de instâncias retidas diminui.
Suspeito que o componente Navigation esteja mantendo a instância de um fragmento quando estiver na pilha de trás e o LeakCanary o esteja vendo como um vazamento.
onDestroyView
com o View Binding.