Programming/Android

메모리 누수 이슈 기록 (LocationListener)

YK Choi 2022. 1. 30. 21:53

LocationListener, LocationManager를 이용하여 현재 위치를 실시간으로 업데이트하는 기능을 구현하고 있는데

LocationManager쪽에서 계속 Leak이 발생했었다.

 

 

나는 Fragment 쪽에서 LocationListener 인터페이스를 implement하고 있었다.

 

destroy될 때 locationManager.removeUpdate() 를 하지 않으면 Leak이 발생할 수 있다는 건 이해가 됐는데,

그렇다면 난 onStop() 쪽에서 removeUpdate()했는데도 왜 발생하는건지 의아했다.

 

시도 1

LocatoinManager를 destroyView할 때 null로 처리를 안해서 그런가? 싶어서

lateinit var locationManager: LocationManager

var locatoinManager: LocationManager? = null

로 바꾸고 destroy될 때 null 처리해보았지만 마찬가지였다.

 

 

시도 2

onStop()쪽에서 디버깅을 시도해서 removeUpdates()가 잘 되는지 확인해보았다.

다음 줄로 넘어가보면 mListener에서 size가 0이 되면서 제거된 상태를 확인할 수 있었다.

그렇다면 Leak이 안나야하는거 아닌가? 라는 생각이 들었다. 뭐가 문제였을까

 

시도 3

onStop()말고 onPause()쪽에서 제어해보기로 하였다. 위치 권한 확인과 실시간 update요청을 onStart()쪽에서 하고 있었기 때문에 onPause()쪽에서 컨트롤하려면 onResume()쪽의 수정을 해야하는 수고가 있겠지만 시험삼아 onPause()쪽에서 테스트해보았다.

결과는 성공.(Leak 발생 안함)

.....?

onPause() 다음에 onStop()의 순서인데 onStop은 안되고, onPause는 된다?

onStop() 내에서 super.onStop()을 호출한 뒤에 removeUpdates()를 호출하고 있었는데 이 순서를 바꾸어보았다.

override fun onStop() {
    binding.naverMapview.onStop()
    locationManager.removeUpdates(this)
    super.onStop()
}

결과는 이번에도 성공

 

하지만 잠시 시간이 흐른 뒤에 알게된 것은.. leak이 나기도하고 안나기도 한다는 것이다.

 

다시 고민에 빠졌다. 원인이 무엇일까

 

다음 시도

조금 더 자료를 찾아보니 아래와 같은 글을 보았다.

https://stackoverflow.com/questions/43135948/memory-leak-when-removing-location-update-from-a-fragment-in-onpause

 

Memory leak when removing location update from a fragment in onPause

In one of the fragments in my app, I require location updates in order to determine when the user is near a short list of locations so relevant information is available to the user. When I create a

stackoverflow.com

LocationListener를 사용하면서 나와 같은 이슈는 오랫동안 존재했던(long-running issue) 문제였다고한다.

 

LocationListener를 WeakReference로 wrapping 하여 누수를 해결할 수 있다고 한다. 이 부분은 우선 이대로 진행하고, 구현이 끝나면 수정해봐야겠다.