Escrever e visualizar registros com o Logcat

A janela Logcat no Android Studio mostra mensagens do sistema, como quando ocorre uma coleta de lixo, e mensagens que você adicionou ao seu app com a classe Log. Ela mostra mensagens em tempo real e mantém um histórico para que você possa conferir mensagens mais antigas.

Para mostrar apenas as informações do seu interesse, você pode criar filtros, determinar quantas informações aparecerão nas mensagens, definir níveis de prioridade, mostrar apenas mensagens produzidas pelo código do app e fazer uma pesquisa pelo registro. Por padrão, o Logcat só mostra a saída de registro relacionada ao app executado mais recentemente.

Quando um app gera uma exceção, o Logcat mostra uma mensagem seguida do stack trace associado contendo links para a linha de código.

A janela "Run" mostra mensagens de registro do app em execução. Você pode configurar a tela de saída do Logcat, mas não a janela "Run".

Conferir registros do app

Para mostrar as mensagens de registro de um app:

  1. Crie e execute seu app em um dispositivo.
  2. Clique em View > Tool Windows > Logcat ou clique em Logcat na barra da janela de ferramentas.

A janela do Logcat mostra as mensagens de registro do app selecionadas no menu na parte de cima da janela, como mostrado na Figura 1.

Figura 1. A janela do Logcat.

Por padrão, o Logcat mostra apenas as mensagens de registro do app em execução no dispositivo. Para mudar esse padrão, confira como filtrar mensagens do Logcat.

A barra de ferramentas do Logcat apresenta os seguintes botões:

  1. Clear logcat : clique para limpar o registro visível.
  2. Scroll to the end : clique para pular para o final do registro e conferir as mensagens mais recentes. Se você clicar em uma linha no registro, a exibição vai pausar a rolagem nesse ponto.
  3. Up the stack trace e Down the stack trace : clique para navegar para cima e para baixo nos stack traces no registro, selecionando o nome de arquivo anterior ou seguinte que aparece nas exceções impressas. Esse é o mesmo comportamento de quando você clica em um nome de arquivo no registro.
  4. Use soft wraps : clique para ativar a quebra de linha e impedir a rolagem horizontal. No entanto, qualquer string inquebrável ainda exige rolagem horizontal.
  5. Print : clique para imprimir as mensagens do Logcat. Depois de selecionar suas preferências de impressão na caixa de diálogo mostrada, você também pode salvar as mensagens em PDF.
  6. Restart : clique para limpar o registro e reiniciar o Logcat. Ao contrário do botão Clear logcat, esse botão recupera e mostra mensagens de registro anteriores. Por isso, ele é mais útil se o Logcat não responder e você não quiser perder suas mensagens de registro.
  7. Logcat header : clique para abrir a caixa de diálogo Configure Logcat Header, em que é possível personalizar a aparência de cada mensagem do Logcat, como a exibição da data e da hora.
  8. Screen capture : clique para criar uma captura de tela.
  9. Screen record : clique para gravar um vídeo da tela do dispositivo por no máximo três minutos.

Escrever mensagens de registro

A classe Log permite criar mensagens de registro que aparecem no Logcat. Cada mensagem do registro do Android é associada a uma tag e uma prioridade. A tag de uma mensagem de registro do sistema é uma string curta que indica o componente do sistema que originou a mensagem.

Use os seguintes métodos de registro, listados em ordem decrescente de prioridade:

Uma tag definida pelo usuário pode ser qualquer string que você ache útil, como o nome da classe atual. Você define a tag em uma chamada de método Log, por exemplo:

Kotlin

Log.d(tag, message)

Java

Log.d(tag, message);

Consulte a descrição da classe Log para conferir uma lista mais completa de opções.

Nunca compile registros detalhados no seu app, exceto durante o desenvolvimento. Os registros de depuração são compilados, mas removidos no tempo de execução. Os registros de erros, avisos e informações são sempre mantidos.

Para cada método de registro, o primeiro parâmetro precisa ser uma tag exclusiva e o segundo, uma mensagem. A tag de uma mensagem de registro do sistema é uma string curta que indica o componente do sistema que originou a mensagem. Uma tag pode ser qualquer string que você ache útil, como o nome da classe em questão.

Uma boa prática geral é declarar uma constante TAG na classe para usar no primeiro parâmetro. Por exemplo, você pode criar uma mensagem de informação de registro da seguinte forma:

Kotlin

private const val TAG = "MyActivity"
...
Log.i(TAG, "MyClass.getView() — get item number $position")

Java

private static final String TAG = "MyActivity";
...
Log.i(TAG, "MyClass.getView() — get item number " + position);

Observação: os nomes de tag com mais de 23 caracteres ficam truncados na saída do Logcat.

Formato das mensagens do Logcat

O formato das mensagens do registro é:

date time PID-TID/package
priority/tag: message

PID significa "identificador do processo" e TID significa "identificador da linha de execução". Eles podem ser iguais se houver apenas uma linha de execução.

Por exemplo, a mensagem de registro a seguir tem prioridade V e uma tag AuthZen:

12-10 13:02:50.071 1901-4229/com.google.android.gms V/AuthZen: Handling delegate intent.

Definir o nível de registro

Você pode definir o nível de registro para controlar se o Logcat mostra todas as mensagens ou apenas as mensagens que indicam as condições mais graves.

O Logcat continua a coletar todas as mensagens, independente da configuração do nível de registro. A configuração determina apenas o que o Logcat mostra.

No menu Log level, selecione um dos valores a seguir:

  • Verbose (detalhado): mostra todas as mensagens de registro (padrão).
  • Debug (depuração): mostra as mensagens de registro da depuração que são úteis apenas durante o desenvolvimento, além de mensagens de nível inferior dessa lista.
  • Info (informações): mostra mensagens de registro esperadas para uso regular, além de mensagens de nível inferior dessa lista.
  • Warn (aviso): mostra possíveis problemas que ainda não são erros, além de mensagens de nível inferior dessa lista.
  • Error (erro): mostra problemas que causaram erros, além de mensagens de nível inferior dessa lista.
  • Assert (afirmação): mostra problemas que o desenvolvedor acredita que nunca acontecerão.

Pesquisar mensagens do Logcat

Para pesquisar as mensagens atualmente exibidas no Logcat:

  1. (Opcional) Selecione Regex se quiser usar um padrão de pesquisa de expressão regular.
  2. Digite uma sequência de caracteres no campo de pesquisa .

    A exibição da saída do Logcat é modificada conforme necessário.

  3. Pressione Enter para armazenar a string de pesquisa no menu durante essa sessão.
  4. Para repetir a pesquisa, selecione-a no menu de pesquisa. Marque ou desmarque Regex conforme necessário.

Filtrar mensagens do Logcat

Uma forma de reduzir a saída de registros a um nível gerenciável é restringi-la com um filtro.

Observação: o filtro se aplica ao seu histórico completo do Logcat, não apenas às mensagens mostradas atualmente. Verirfique se as outras opções de exibição estão configuradas corretamente para poder conferir a saída do filtro que você quer examinar.

Para definir e aplicar um filtro:

  1. No menu de filtragem, selecione uma opção de filtro:
    • Show only selected application: mostra somente as mensagens produzidas pelo código do app (padrão). O Logcat filtra as mensagens de registro usando o PID do app ativo.
    • No Filters: não aplica filtros. O Logcat mostra todas as mensagens de registro do dispositivo, independente do processo selecionado.
    • Edit Filter Configuration: cria ou modifica um filtro personalizado. Por exemplo, você pode criar um filtro para conferir mensagens de registro de dois apps ao mesmo tempo.

    Depois de definir os filtros, você pode selecioná-los no menu. Para removê-los do menu, basta excluí-los.

  2. Se você selecionou Edit Filter Configuration, crie ou modifique um filtro.
    1. Especifique os parâmetros do filtro na caixa de diálogo Create New Logcat Filter:
      • Filter Name: insira o nome de um filtro que você quer definir ou selecione um filtro existente no painel esquerdo para modificá-lo. O nome pode conter apenas caracteres minúsculos, sublinhados e dígitos.
      • Log Tag: permite especificar uma tag.
      • Log Message: permite especificar o texto da mensagem de registro.
      • Package Name: permite especificar o nome de um pacote.
      • PID: permite especificar um ID de processo.
      • Log Level: permite selecionar um nível de registro.
      • Regex: selecione essa opção para usar uma sintaxe de expressão regular para esse parâmetro.
    2. Clique em + para adicionar a configuração de filtro no painel esquerdo.

      Para remover um filtro, selecione-o no painel esquerdo e clique em -.

    3. Quando terminar, clique em OK.

Se as mensagens de registro que você quer não aparecerem, selecione No filters e pesquise as mensagens de registro específicas.

Ler mensagens da coleta de lixo

Às vezes, quando um evento de coleta de lixo (GC) ocorre, as informações são impressas no Logcat.

Para conferir mais detalhes sobre a memória do app, use o Memory Profiler.

Mensagens de registro da Dalvik

Na Dalvik, mas não na ART, toda GC imprime as seguintes informações no Logcat:

D/dalvikvm(PID): GC_Reason Amount_freed,
Heap_stats, External_memory_stats, Pause_time

Exemplo:

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms

Enquanto as mensagens de registro se acumulam, procure identificar aumentos nas estatísticas de heap. Se esse valor continuar aumentando, é possível que haja um vazamento de memória.

Os seguintes termos estão incluídos nas mensagens de registro da Dalvik:

Motivo da GC
O que acionou a GC e o tipo de coleta. Os motivos possíveis são:
GC_CONCURRENT
Uma GC simultânea que libera memória à medida que o heap começa a ficar cheio.
GC_FOR_MALLOC
Uma GC foi causada porque o app tentou alocar memória quando o heap já estava cheio e, por isso, o sistema teve que parar o app e recuperar memória.
GC_HPROF_DUMP_HEAP
Uma GC que ocorre quando você solicita a criação de um arquivo HPROF para analisar o heap.
GC_EXPLICIT
Uma GC explícita, como quando você chama gc(). No entanto, evite chamar esse método. Em vez disso, confie na execução do GC quando necessário.
GC_EXTERNAL_ALLOC
Uma GC da memória alocada externamente, como os dados de pixel armazenados na memória nativa ou em buffers de byte NIO. Isso acontece apenas na API de nível 10 e anteriores. As versões mais recentes alocam tudo no heap da Dalvik.
Quantidade liberada
A quantidade de memória recuperada por essa GC.
Estatísticas de heap
Percentual livre do heap e (número de objetos ativos)/(tamanho total do heap).
Estatística da memória externa
Memória alocada externamente na API de nível 10 e anteriores (quantidade de memória alocada)/(nível a partir do qual a coleta ocorre).
Tempo de pausa
Os heaps maiores têm tempos de pausa maiores. Os tempos de pausa simultâneos mostram duas pausas: uma no início da coleta e outra perto do fim.

Mensagens de registro da ART

Ao contrário da Dalvik, a ART não registra mensagens para GCs que não forem solicitadas explicitamente. As informações da GC só são impressas quando a GC é explícita ou a pausa da GC excede 5 ms ou a duração da GC excede 100 ms. Se o app não estiver em um estado perceptível de pausa, como quando ele estiver em segundo plano, em que o usuário não consegue perceber uma pausa da GC, nenhuma informação da GC vai ser mostrada, exceto as GCs explícitas.

A ART oferece as seguintes informações nas mensagens de registro das coletas de lixo:

I/art: GC_Reason GC_Name Objects_freed(Size_freed) AllocSpace Objects,
    Large_objects_freed(Large_object_size_freed) Heap_stats LOS objects, Pause_time(s)

Exemplo:

I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects,
    21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms

Os seguintes termos estão incluídos nas mensagens de registro da ART:

Motivo da GC
O que acionou a GC e o tipo de coleta. Os motivos possíveis são:
Concurrent
Uma GC simultânea que não suspende as linhas de execução do app. Essa GC é executada em uma linha de execução em segundo plano e não impede alocações.
Alloc
Uma GC iniciada porque o app tentou alocar memória quando o heap já estava cheio. Nesse caso, a coleta de lixo ocorreu na linha de execução de alocação.
Explicit
A coleta de lixo foi solicitada explicitamente por um app, por exemplo, chamando System.gc() ou Runtime.gc(). No entanto, assim como na Dalvik, a prática recomendada no ART é confiar na GC e evitar a solicitação de GCs explícitas, se possível. GCs explícitas não são recomendadas porque bloqueiam a linha de execução de alocação e gastam ciclos de CPU de forma desnecessária. As GCs explícitas também podem gerar instabilidade (repetições involuntárias, inconstância ou lentidão no app) se causarem a interrupção forçada de outras linhas de execução.
NativeAlloc
Uma GC causada pela pressão da memória nativa pelas alocações nativas, como bitmaps ou objetos de alocação RenderScript.
CollectorTransition
Uma GC causada por uma transição de heap. Isso é causado pela mudança da estratégia de GC no tempo de execução, como quando o app muda entre estados perceptíveis de pausa. As transições do coletor consistem em copiar todos os objetos de um espaço apoiado por lista livre para um espaço de ponteiro de incremento simples ou vice-versa.

Isso ocorre apenas em dispositivos com pouca RAM que executam uma versão do Android anterior à 8.0 quando um app muda os estados do processo de um estado perceptível. Por exemplo, quando o app está em primeiro plano, o usuário pode notar uma pausa da GC em um estado não pausado perceptível ou vice-versa.

HomogeneousSpaceCompact
A compactação homogênea de espaço é a mudança de espaço de lista livre para compactação de espaço de lista livre que normalmente ocorre quando um app é movido para um estado de pausa imperceptível do processo. Os principais motivos que levam a isso são a redução do uso de RAM e a desfragmentação do heap.
DisableMovingGc
Esse não é um motivo da GC, mas uma observação de que a coleta foi bloqueada devido ao uso de GetPrimitiveArrayCritical enquanto a compactação de heap simultânea está ocorrendo. Em geral, o uso de GetPrimitiveArrayCritical não é recomendado de forma alguma em virtude das restrições aos coletores de movimento.
HeapTrim
Esse não é um motivo de GC, mas uma observação de que a coleta está bloqueada até o corte do heap acabar.
Nome da GC
O ART tem várias GCs:
Concurrent mark sweep (CMS)
Um coletor de todo o heap que coleta todos os espaços, menos o espaço de imagem.
Concurrent partial mark sweep
Um coletor de quase todo o heap que coleta todos os espaços, menos os espaços de imagem e zigoto.
Concurrent sticky mark sweep
Um coletor geracional que só consegue liberar objetos alocados desde a última GC. Essa coleta de lixo é executada com mais frequência do que uma mark sweep completa ou parcial, já que é mais rápida e tem pausas mais curtas.
Marksweep + semispace
Uma GC não simultânea de cópia usada para transições do heap e para compactação homogênea de espaços para desfragmentar o heap.
Objetos liberados
O número de objetos que foram recuperados por essa GC do espaço dos objetos não grandes.
Volume liberado
O número de bytes que foram recuperados por essa GC do espaço dos objetos não grandes.
Objetos grandes liberados
O número de objetos no espaço de objetos grandes que foram recuperados por essa coleta de lixo.
Volume liberado dos objetos grandes
O número de bytes no espaço de objetos grandes que foram recuperados por essa coleta de lixo.
Estatísticas de heap
Percentual livre e (número de objetos ativos)/(tamanho total do heap).
Tempos de pausa
Em geral, os tempos de pausa são proporcionais ao número de referências a objeto que foram modificadas durante a execução da GC. No momento, as GCs de CMS da ART só têm uma pausa, que é próxima ao fim da GC. As GCs de movimento têm uma pausa longa que representa a maior parte da duração da GC.

Se você perceber uma grande quantidade de mensagens de GC no Logcat, procure aumentos nas estatísticas de heap. Se esse valor continuar aumentando e nunca parecer ficar menor, é possível que haja um vazamento de memória.

Como alternativa, se você perceber GCs que especificam o motivo "Alloc", isso significa que você já está operando perto da capacidade máxima do heap e pode esperar exceções fora da memória em breve.