[Android] 앱이 갑자기 꺼지는 이슈

이번 포스트는 며칠전에 맞닥들인 이슈와 해결을 서술할까 합니다.

WTF?

구글맵을 사용하는 앱을 한창한창 개발중에 이슈가 터졌습니다.
구글맵 화면에서 마커를 보여주거나 이미지를 보여주는등 이런저런 처리를 하는데 앱의 퍼포먼스가 갑자기 떨어지기 시작했습니다.
그러더니 앱이 갑자기 꺼지는 사태가.. 심지어 앱이 비정상 종료되었고 다시 실행하겠냐는 팝업이 뜨지 않았습니다.
테스트로 사용한 폰은 무려 Galaxy S8+였는데..
사실 이 페이지를 그때 생성한것이 아니고 한달전부터 생성해서 써오던 페이지였는데 이런 크리티컬한 이슈라니 조금 황당했습니다.

원인을 찾자

항상 하던대로 로그캣을 켜봤습니다.

?!
앱이 강제 종료 되었는데.. 평소에 보이던 빨간 에러로그는 찾을 수 없었습니다.
재현 증상을 발견하기 위해 몇번 동일한 방법으로 테스트 해봤더니 역시나 뜨지 않더군요..

의심이 가는 부분은 로그캣 마지막 줄에 보이는 GC(Garbage Collector)에 관한 로그였습니다.

Android Studio를 3.1.2로 업데이트 하면서 이전에 잘 사용하지 않던 Profiler를 켜봤습니다.
그리고 재현 경로를 반복 실행하여 테스트를 다시 실시하였습니다.

메모리 사용량 때문이 맞는 것 같다

재현 경로(빨간 박스 부분에 보라색 점)에 맞춰 중간까지 메모리가 계속 치솟다가 줄어들면서 앱이 꺼집니다.
거의 저 중간 시점부터 퍼포먼스가 느려지는것을 확인할 수 있었습니다.
메모리 최대 사용량은 600Mb까지 올라갔다가 떨어졌습니다.

해당 부분 코드를 확인해보니 GroundOverlay에서 이미지 할당은 계속 하는데 안쓰는 값에 대해서는 제때 해제를 하지 않아서 나타나는 현상이였습니다.
작은 이미지로 테스트 해 본 결과 맵 위에 해당 이미지들이 겹쳐져서 계속 쓰여지고 있었습니다.
아마 큰 이미지를 계속 쓰고있어서 서로 겹치는지 육안으로 확인이 안됐기 때문에 더 늦게 발견한 것 같습니다.

방어코드 적용

간단히 방어코드를 작성하였습니다.
GroundOverlay 객체를 안쓰는 시점에서 해제해주면됩니다.

1
2
3
4
GroundOverlay overlay = googleMap.addGroundOverlay(overlayOptions);
// ...
overlay.remove(); // 안쓰는 시점에서 해제
overlay = null;

이제 필요없는 GroundOverlay는 지도에서 삭제될 것입니다.

결과

해당 코드를 적용후 다시 실행해보았습니다.

이전에 비해서 확실히 메모리를 덜 쓰고 있다는 것을 알 수 있습니다.
최대 300Mb 선에서 더 올라가지 않았습니다.

메모리 사용 영역(파란색 그래프)를 한번 클릭하면 더 자세히 볼 수 있습니다.

쓰레기통 아이콘으로 가비지컬렉터가 언제 작동하고 그에따른 메모리의 변화도 같이 볼 수 있어 편합니다.

마무리

어쩌면 미궁으로 빠질 수 있었던 문제였습니다.
다행히 찍기(?)로 문제를 확인하고 해결할 수 있었는데 개발자는 다양한 문제에 접하고 해결하는 것도 성장하는 방법이라고 생각합니다.
이러한 경험치들이 쌓이면 더 빨리 어떤 문제에 대해서 해결 할 수 있으니 퍼포먼스도 좋아질 것입니다.

Android Profiler를 써본 소감은 실시간으로 앱의 상태를 확인 할 수 있어 편리했습니다.
무거운 앱을 만들 일이 없어서 사용 안했었는데 앞으로 자주 접할 것 같습니다.
Profiler에 대해서 더 궁금해졌으니 조만간 분석해보고 사용방법이나 나만의 팁을 포스팅하겠습니다.

그럼 좋은하루되세요!