본문 바로가기

Android 공부

2. 비정상 종료와 ANR

올해 초에 어플을 배포하고 난 후부터 가장 듣기 싫었던 단어가 비정상 종료와 ANR 이라고 해도 과언이 아닐 정도로 악명 높은 두 주제에 대해 다뤄보려 한다. 사실 이 둘은 어려운 원리나 이론을 가지고 있다기 보다 원인을 찾기 어렵고, 원인을 찾는다고 해도 바로 고쳐지지 않는 경우가 많기 때문에 더 어렵게 다가온다. 둘은 모두 Android vitals 를 사용하여 발생률을 확인할 수 있고 원인을 찾아볼 수 있다. 

 

현재 배포된 어플에서 확인할 수 있는 비정상 종료 및 ANR 수치이다.

 

 


비정상 종료

안드로이드 공식 문서에 따르면 처리되지 않은 예외나 신호로 인해 예상치 못한 종료가 발생할 때마다 비정상 종료로 인식되고, 배포된 어플의 경우 android vitals를 통해 확인이 가능하다. 앱이 비정상 종료되면 Android는 앱 프로세스를 종료하고 대화상자를 표시하여 그림 1과 같이 앱이 중지되었음을 사용자에게 알려준다. 이는 일일 활성 사용자의 일정 비율 이상이 비정상 종료를 경험했을 때를 기준으로 개발자에게 알려준다. 현재 참여하고 있는 프로젝트에서 배포한 어플도 android vitals에서 그 내용을 확인할 수 있고 스택 트레이스를 통해 어떤 위치에서 발생하는 오류인지를 확인하고 있다. 

 

스택트래이스에서 확인할 수 있는 상세 내용

 

위와 같은 상세 내용에는 어떤 버전에서 발생했는지, 포그라운드인지 백그라운드인지 등의 정보도 포함되어 있다. 공식 문서에 따르면 스택 트레이스에는 발생한 예외 유형, 예외가 발생한 코드 섹션이 제공된다고 한다. 일반적으로 가장 위에 적힌 "유형" 부분은 강력한 힌트가 되며 나 역시도 스택 트레이스에서 제공하는 에러 유형을 이용하여 자료를 검색하고 해결한다. 유형에는 메모리 오류, 네트워킹 예외, null pointer 예외가 있다. 특히 null pointer예외의 경우는 비정상 종료의 가장 큰 원인이 되며 나 역시도 수십개의 null pointer 예외를 마주한 적이 있다.. 

 

 

 

 

ANR

ANR은 Application Not Responding의 약자로 말 그래도 어플리케이션이 응답하지 않을 때 (앱의 UI스레드가 오랫동안 차단되는 경우) 발생하는 오류이다. 앱의 기본 스레드가 사용자의 이벤트를 처리하지 못했을 경우 발생하는 오류인데, 기본 스레드에 대해서는 다른 게시물에서 자세히 다룰 예정이다. ANR 역시 android vitals 에서 그 내용을 확인할 수 있으며 공식 문서에 따르면 다음과 같은 일반적인 패턴으로 원인이 확인된다고 한다. 

 

  • 앱이 기본 스레드에서 I/O와 관련된 느린 작업을 실행 중.
  • 앱이 기본 스레드에서 긴 계산을 실행 중.
  • 기본 스레드에서 다른 프로세스에 관한 동기 바인더 호출을 실행 중이고 다른 프로세스가 반환하는 데 오랜 시간이 소요됨.
  • 다른 스레드에서 발생하는 긴 작업을 위해 동기화된 블록을 대기하는 동안 기본 스레드가 차단됨.
  • 기본 스레드가 프로세스에서 또는 바인더 호출을 통해 다른 스레드와 교착 상태에 있음. 기본 스레드가 긴 작업이 완료될 때까지 대기하는 것만이 아니라 교착 상태에 있음.

 

위의 비정상적 종료와는 다르게 아직 내가 배포한 어플에서 ANR은 발생 기록이 없는 상태이다. 코드의 완결성 보다는 ANR이 발생하는 경우 배포하기 전 개발하는 과정에서 이미 에러가 발생해 해결할 수 밖에 없는 상황이었던 것 같다. 메인 스레드에서 작업하면 안된다는 에러를 마주하고 코드를 고쳤던 경험이 여기에 해당하지 않을까 싶다.

 


 

비정상 종료와 ANR은 개발자 콘솔에서 버전별로 확인할 수 있고, 조건을 걸어 탐색이 가능하다. 하지만 에러가 해결된 경우 다음 버전에서 다시 해당 에러가 리마인드 되지 않고 해결 방안을 기록하기 어렵기 때문에 나는 error history라는 문서를 만들어 정리하면서 같은 에러가 발생할 경우 대처하고 있다. 

에러를 기록하기 시작했던 초반 기록들
아직 해결 여부를 확인할 수 없는 에러들도 존재한다.

아직 완전히 동일한 에러가 발생한 적은 없지만 에러 유형은 계속 돌아가면서 반복되고 있다. 이렇게 문서화해서 관리하는 것이 나중에 기억도 잘 나고 공부하는데 도움도 될 것 같다.