H.Nguyen H.Nguyen - 1 month ago 14
Android Question

Why Rxjava could cause memory leaking

I'm playing with rxjava and found there is a risk of memory leak if a subscription is not completed before an activity is destroyed because "observables retain a reference to the context". One of the demos for such case is given as below, if the subscription is not unsubscribed onDestroyed (source: https://github.com/dlew/android-subscription-leaks/blob/master/app/src/main/java/net/danlew/rxsubscriptions/LeakingActivity.java):

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_leaking);

// This is a hot Observable that never ends;
// thus LeakingActivity can never be reclaimed
mSubscription = Observable.interval(1, TimeUnit.SECONDS)
.subscribe(new Action1<Long>() {
@Override public void call(Long aLong) {
Timber.d("LeakingActivity received: " + aLong);
}
});
}


However I'm not sure why such a leak exists. I've checked the Observable class and seen nothing relevant to Context. So all I can think of is because there is an anonymous Action1 class defined within the subscribe method which hold a reference to the activity instance. And the observable in turn holds a reference to the action. Am I right?

Thanks

Answer

The .subscribe(new Action1<Long>() { }) creates and stores nested class which as any non-static nested class has reference to containg class instance - in this case the Activity.

To resolve that you can Subscription.unsubscribe the mSubscription in the Activity.onDestroy

Comments