메모리 누수
메모리 누수(Memory Leak)란 보통 참조가 완료되었지만 할당한 메모리를 해제하지 않았을 때 발생.
특히, 강한 참조의 경우 가비지 컬렉터가 메모리에서 객체를 제거할 수 없으므로 라이프 사이클에 맞게 객체 참조를 끊어주어야 메모리 해제가 가능하다.
메모리 누수는 시스템 전체 성능에 영향을 미친다.
*
Observable은 안드로이드의 컨텍스트(Context)를 복사하여 유지한다.
onComplete(), onError() 함수가 호출되면 내부에서 자동으로 unsubscribe() 함수를 호출하여 메모리를 해제해준다.
하지만, 액티비티가 비정상적으로 종료되면 액티비티가 종료되어도 가비지 컬렉션의 대상이 되지 못하는 경우가 발생할 수 있으며, 이 때 메모리 누수가 발생하게 된다.
메모리 누수 해결방안
Disposable 인터페이스를 이용한 명시적 자원 해제
- onCreate() 에서 subscribe()를 호출하면 onDestory() 에서 메모리 참조를 해제.
- onResume()에서 subscribe()를 호출하면 onPause() 에서 메모리 참조를 해제.
RxLifecycle 라이브러리 이용
액티비티의 부모를 RxAppCompatActivity로 변경하고 compose() 함수를 사용하여 RxLifecycle 라이브러리를 적용.
public class SampleRxLifecycle extends RxAppCompatActivity {
prvate Unbinder mUnbinder;
...
Observable.create(~)
//.compose(bindToLifecycle())
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(~);
...
@Override
public void onDestroy() {
super.onDestroy();
if (mUnbinder != null) {
mUnbinder.unbind();
}
}
...
}
compose(bindToLifecycle()) 함수를 사용하게 되면, onCreate - onDestroy, onResume - onPause 메서드가 쌍으로 동작한다. 즉, onCreate에서 subscribe를 호출하면 onDestroy에서 unsubscribe를 호출한다.
bindUntilEvent 함수를 선언하면 종료되는 시점을 직접 설정할 수 있다.
ActivityEvent를 활용해 종료되는 시점을 선택할 수 있다.
public enum ActivityEvent {
CREATE,
START,
RESUME,
PAUSE,
STOP,
DESTROY
}
CompositeDisposable 클래스 이용
CompositeDisposable 클래스를 이용하면 생성된 모든 Observable을 안드로이드 라이프 사이클에 맞춰 한번에 모두 해제할 수 있다.
사용하는 방법은, 첫 번째 해결책의 연장선이다.
첫 번째 해결책은 DisposableObserver 객체를 직접 해지하는 반면,
이 방법은 Publisher.subscribe() 를 이용하여 Disposable을 리턴한 후 CompositeDisposable 클래스에서 일괄적으로 처리하는 방식이다.
Publisher.subscribe()는 return 값이 void 이므로, subscribeWith() 함수를 사용하거나 인자에 소비자(Consumer)를 전달해 Disposable 객체를 리턴받아야 한다.
'Language > RxJava' 카테고리의 다른 글
[RxJava] 7장. 디버깅과 예외 처리 2 - 예외 처리 (0) | 2020.06.16 |
---|---|
[RxJava] 7장. 디버깅과 예외 처리 1 - 디버깅(Debugging) (0) | 2020.06.15 |
[RxJava] 6장. 안드로이드의 RxJava 활용 3 - Thread (0) | 2020.06.12 |
[RxJava] 6장. 안드로이드의 RxJava 활용 2 - RecyclerView 클래스 (0) | 2020.06.11 |
[RxJava] 6장. 안드로이드의 RxJava 활용 1 - RxAndroid 소개 (0) | 2020.06.11 |