问:RxJava:clear(CompositeDisposable)方法在内部如何工作 [英] Q : RxJava : How the clear (CompositeDisposable) method work internally

查看:254
本文介绍了问:RxJava:clear(CompositeDisposable)方法在内部如何工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

匿名类包含对封闭类的引用.

Anonymous class hold a reference to the enclosing class.

在下面的示例中,我创建了一个小活动.在onCreate方法中,我只是在另一个线程上添加了一个计时器,添加了CompositeDisposable并在onDestroy中将其清除.

In the following example, I created a small Activity. In the onCreate method, I just add a timer on another Thread, add a CompositeDisposable and clear it in the onDestroy.

很明显,如果没有CompositeDisposable,它将导致内存泄漏.使用CompositeDisposable,它不会产生任何内存泄漏,但是它甚至如何工作?

Obviously without the CompositeDisposable, it will create a memory leak. With the CompositeDisposable it doesn't create any memory leak but how is it even working ?

RxJava只是中断线程并在每次回调中都将null设置为?您能否提供一些可以在RxJava源代码中完成此工作的行,我想它就在dispose方法附近.

RxJava just interrupt the Thread and put null on every callback ? Can you provide some line that do this work in RxJava source code, i suppose it's somewhere near the dispose method.

public class MainActivity extends AppCompatActivity {

private String TAG = "MainActivity";

private CompositeDisposable composite = new CompositeDisposable();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    composite.add(Flowable
            .just(1)
            .timer(90, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .subscribeWith(new DisposableSubscriber<Long>() {

                @Override
                public void onNext(Long aLong) { sayHello(); }

                @Override
                public void onError(Throwable t) { sayHello(); }

                @Override
                public void onComplete() { sayHello(); }
            }));
}

@Override
protected void onDestroy() {
    super.onDestroy();

    composite.clear();
}

public void sayHello () { Log.w(TAG, "Hello everyone"); }

推荐答案

它恰好位于dispose方法的源代码中.您可能也可以在IDE的库中跳转到方法的源,在IntelliJ中,它是Windows上的 Ctrl + B ⌘B在Mac上,在Eclipse中是 F3 .

It is precisely in the source of the dispose method. You can probably jump into the source of methods in your libraries within your IDE as well, in IntelliJ it's Ctrl+B on Windows or ⌘B on Mac, and in Eclipse it's F3.

无论如何,这是dispose方法的来源(我的评论):

Anyhow, here's the source of the dispose method (comments mine):

@Override
public void dispose() {
    if (disposed) { // nothing to do
        return;
    }
    OpenHashSet<Disposable> set; // this is the same type as our field that holds the Disposables
    synchronized (this) {
        if (disposed) { 
            return; // another thread did it while we got our lock, so nothing to do
        }
        disposed = true; // setting this flag is safe now, we're the only ones disposing
        set = resources; // the references are now in this local variable
        resources = null; // our field no longer has the references
    }

    dispose(set); // from here on out, only this method has the references to the Disposables
}

然后是我们在最后一行中在上面调用的dispose(OpenHashSet<Disposable>)方法的完整代码(主要是错误处理,我认为这是不言而喻的):

And then the complete code of the dispose(OpenHashSet<Disposable>) method that we called above on the last line (mostly just error handling which I believe is self-explainatory):

/**
 * Dispose the contents of the OpenHashSet by suppressing non-fatal
 * Throwables till the end.
 * @param set the OpenHashSet to dispose elements of
 */
void dispose(OpenHashSet<Disposable> set) {
    if (set == null) {
        return;
    }
    List<Throwable> errors = null;
    Object[] array = set.keys();
    for (Object o : array) {
        if (o instanceof Disposable) {
            try {
                ((Disposable) o).dispose();
            } catch (Throwable ex) {
                Exceptions.throwIfFatal(ex);
                if (errors == null) {
                    errors = new ArrayList<Throwable>();
                }
                errors.add(ex);
            }
        }
    }
    if (errors != null) {
        if (errors.size() == 1) {
            throw ExceptionHelper.wrapOrThrow(errors.get(0));
        }
        throw new CompositeException(errors);
    }
}

如您所见,在该方法的结尾,由于没有人持有set的引用,因此现在可以对其进行垃圾回收.

As you can see, at the end of that method, set can now be garbage collected, as nobody is holding a reference to it.

这篇关于问:RxJava:clear(CompositeDisposable)方法在内部如何工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆