Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 724
H.Nguyen Avatar asked Oct 05 '16 12:10

H.Nguyen


1 Answers

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

like image 194
miensol Avatar answered Nov 16 '22 07:11

miensol