Vale a pena ter em mente que embora esta ferramenta possa ser muito útil para encontrar referências a uma suspeita de fuga, pode ser bastante difícil e complexo de usar para encontrar fugas desconhecidas e requer um pouco de análise. Dizendo que, se você dominar – é uma ótima ferramenta para ter debaixo do cinto!
LeakCanary
Parece que encontrou o nosso vazamento! Se clicarmos nele, veremos o vestígio completo da fuga:
Está a dizer-nos que o TaskActivity está a vazar e as referências sublinhadas mostram o vestígio, está a vazar de mContext
em SingletonExample
– parece-me familiar! Agora sabemos como encontrar um vazamento usando o LeakCanary. 😃
Anular fugas de memória
Então, agora que encontramos a fuga de memória, como podemos evitá-las no futuro? Abaixo estão algumas das causas e padrões mais comuns.
Receptores de radiodifusão
Receptores de radiodifusão podem ser usados para ouvir eventos ou intenções de transmissão em todo o sistema que indicam informações do dispositivo, tais como bateria fraca, A data e a conectividade muda – por exemplo, o modo de avião foi desligado. Ao usá-los, precisamos lembrar de cancelar o registro dos receptores de transmissão, caso contrário, inevitavelmente manteremos uma referência à atividade.
Como evitá-la: Tudo que você precisa fazer é chamar unregister()
no seu receptor de broadcast em onStop()
na sua atividade.
Este padrão também é encontrado para asyncTask, TimerTask e threads que precisam ser cancelados em onDestroy()
para evitar um vazamento.
Contexto para a classe Singleton
Por vezes precisamos passar em contexto de uma atividade para uma classe Singleton. Um exemplo disso seria uma classe utils onde precisamos acessar recursos, serviços ou arquivos internos. No entanto, passar em contexto significa que inevitavelmente nos agarramos a uma referência à atividade.
Como evitá-la: Ao invés de passar em this
de uma atividade, podemos passar em contexto de aplicação se ela estiver disponível (se você quiser aprender mais sobre quando usar qual contexto, eu achei este artigo realmente útil!). Uma solução alternativa é garantir que o contexto Singleton seja nulo dentro da actividade onDestroy()
método.
Referências estáticas
Referenciar uma vista ou uma actividade como estática significa que a referência à actividade não será recolhida. Isto deve ser evitado a qualquer momento.
Como evitá-lo: Se você por algum motivo tiver que fazê-lo, você pode garantir que ele seja destruído, definindo-o como nulo em onDestroy().
Referências a classes internas
As classes internas frequentemente causam vazamentos, mantendo uma referência implícita à classe externa. Isto acontece se a variável de classe é declarada como estática ou se a própria classe não é declarada como estática. Confuso? Sim, mas é fácil de evitar se seguirmos a regra simples abaixo.
Como evitá-la: Faça a classe interna estática para evitar manter uma referência à classe externa e nunca crie uma variável estática de uma classe interna. O mesmo se aplica às classes anônimas.
É isso! Espero que você tenha aprendido algumas coisas sobre vazamentos de memória e como evitá-los. Feliz codificação! 😄
Aqui estão alguns artigos e documentação que achei particularmente úteis quando aprendi sobre vazamentos de memória: