ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RxJava dispose()
    개발/안드로이드 2021. 9. 16. 20:00

    이번 포스트에서는 RxJava를 사용할때 왜 dispose() 함수를 호출해서 메모리 정리를 해야하는지를 사례를 통해서 정리해보고자 한다.

     

    class LeakActivity : AppCompatActivity() {
        private var disposable1 : Disposable? = null
    
        companion object {
            private const val TAG: String = "leak_activity_tag"
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val observeSource = Observable.interval(1, TimeUnit.SECONDS)
            disposable1 = observeSource.subscribe { Log.d(TAG, "subscriber1 value: $it") }
            observeSource.subscribe { Log.d(TAG, "subscriber2 value: $it") }
        }
    
        override fun onDestroy() {
            super.onDestroy()
            Log.d(TAG, "onDestroyCalled")
            disposable1?.dispose()
            disposable1 = null
        }
    }

     

    이 액티비티는 생성하면서 1초 마다 이벤트를 보내는 Observable을 생성하고 두개의 subscriber로 구독하고 있다. 그리고 종료될 때는 첫번째 subscriber만 구독 모델을 해지한다. Activity를 종료하기 전까지는 두 subscriber에서 동시에 로그가 출력되는데

     

    2021-09-16 17:48:01.106 subscriber2 value: 0
    2021-09-16 17:48:01.106 subscriber1 value: 0
    2021-09-16 17:48:02.106 subscriber1 value: 1
    2021-09-16 17:48:02.107 subscriber2 value: 1
    2021-09-16 17:48:03.106 subscriber2 value: 2
    2021-09-16 17:48:03.106 subscriber1 value: 2
    2021-09-16 17:48:04.106 subscriber1 value: 3
    2021-09-16 17:48:04.106 subscriber2 value: 3

     

    액티비티를 종료하고 나면 subscriber2에서 계속 로그가 출력된다. 화면이 없어졌는데도 이벤트를 지속적으로 구독하고 있다.

     

    2021-09-16 17:48:44.907 onDestroyCalled
    2021-09-16 17:48:45.106 subscriber2 value: 44
    2021-09-16 17:48:46.107 subscriber2 value: 45
    2021-09-16 17:48:47.106 subscriber2 value: 46

     

    심각한 것은 백버튼으로 앱을 종료한 후 다시 실행해도 계속 구독하고 있게 된다는 것이다.  아래 로그를 보면 subscriber2 로그가 두번씩 찍히는데 이것은 이전에 남아있는 액티비티에서 구독한 subscriber가 계속 출력되기 때문이다.

     

    2021-09-16 17:50:58.964 subscriber2 value: 0
    2021-09-16 17:50:58.964 subscriber1 value: 0
    2021-09-16 17:50:59.106 subscriber2 value: 178
    2021-09-16 17:50:59.964 subscriber1 value: 1
    2021-09-16 17:50:59.965 subscriber2 value: 1
    2021-09-16 17:51:00.106 subscriber2 value: 179
    2021-09-16 17:51:00.963 subscriber1 value: 2
    2021-09-16 17:51:00.963 subscriber2 value: 2
    2021-09-16 17:51:01.106 subscriber2 value: 180
    2021-09-16 17:51:01.963 subscriber2 value: 3
    2021-09-16 17:51:01.963 subscriber1 value: 3
    2021-09-16 17:51:02.106 subscriber2 value: 181

     

    단발성 이벤트를 구독했다면 큰 문제는 되지 않는다 하지만 위 코드처럼 지속적으로 이벤트를 보낸다면 그리고 subscriber 내부에서 메모리 할당 작업이 포함돼있었다면 메모리 릭이 발생하게 된다. 

    '개발 > 안드로이드' 카테고리의 다른 글

    다크모드 적용기  (0) 2021.10.14
    RxJava - Disposable Deep Dive!  (0) 2021.09.17
    RxJava dispose()  (0) 2021.09.16
    ListAdapter, DiffUtil  (0) 2021.08.20
    Coroutine + Retrofit | Coroutine + Room  (0) 2021.07.22
    suspend fun  (0) 2021.07.22

    댓글 0

Designed by Tistory.