如果可观察对象完成,是否需要取消订阅可观察对象? [英] Do I need to unsubscribe from an Observable if the Observable is finished with?

查看:99
本文介绍了如果可观察对象完成,是否需要取消订阅可观察对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有一个Observable(很热,没有完成),我订阅了它.通常,当我完成Subscription的操作后,必须取消订阅它,以防止内存泄漏.

Let us say I have an Observable (hot, doesn't complete), and I subscribe to it. Ordinarily when I am finished with the Subscription I have to unsubscribe it to prevent memory leaks.

let subject$ = new Subject();

const sub = subject$.subscribe(...);
...
// Need to call sub.unsubscribe() when we are finished
sub.unsubscribe();
sub = null;

但是,如果我不仅完成了Subscription的工作,而且还完成了Observable(Subject)的工作,并且删除了对这两者的所有引用,我是否需要调用unsubscribe方法?

But if instead of just being finished with the Subscription I am also finished with the Observable (Subject) and I remove all reference to both, do I need to call unsubscribe method?

let subject$ = new Subject();

const sub = subject$.subscribe(...);
...
sub = null;
subject$=null;
// Assume I have no other references to these
// Do I need to call sub.unsubscribe() in this case?

我的逻辑告诉我我不这样做,因为SubjectSubscription现在都可以进行垃圾收集,并且即使它们相互引用也将被销毁.还是有一些我不知道的隐藏参考?

My logic is telling my I don't because both the Subject and the Subscription are now eligible for garbage collection, and will be destroyed, even though they reference each other. Or is there some hidden reference I don't know about?

不用担心使用unsubscribetakeUntil或其他机制之间的区别.

Don't worry about the difference between using unsubscribe, takeUntil or other mechanisms.

推荐答案

let subject$ = new Subject();的情况下,清除对SubjectSubscription的引用就足够了,之后所有内容都将被垃圾回收.

In the case of a let subject$ = new Subject(); clearing the references to the Subject and the Subscription will be enough, everything will be garbage collected after that.

当您在对象中订阅Subject时,内存泄漏的风险就变得很现实,并且在清除对象上的所有引用之前,您不要取消订阅Subject.在这种情况下,整个对象将保持活动状态,并且不会被垃圾回收.

The risk of a memory leak gets real when you are subscribing to the Subject in an object, and you don't unsubscribe from the Subject before clearing all the references on the object. In that case, the whole object will remain active and won't be garbage collectable.

让我们举个例子:

class BigClass {
    constructor(observable) {
        this.bigArray = new Array(9999999).fill(0);
        observable.subscribe(x => this.result = x);
    }
    //...
}

let subject = new rxjs.Subject();
let bigObject = new BigClass(subject);
let bigObject1 = new BigClass(subject);
let bigObject2 = new BigClass(subject);
let bigObject3 = new BigClass(subject);

bigObject = null;
bigObject1 = null;
bigObject2 = null;
bigObject3 = null;

在此示例中,清除bigObject上的所有引用时,subject仍在x => this.result = x回调上具有引用,而在bigObject上具有引用,从而使其整体上无法收集.

In this example, when clearing all the references on bigObject, the subject still has a reference on the x => this.result = x callback which has a reference on bigObject, making it uncollectable as a whole.

通过取消订阅或清除subject,这将破坏使bigObject保持活动状态的引用链,并且可以进行垃圾回收.

Either by unsubscribing, or clearing the subject, this will break the references chain that keeps bigObject alive, and it will be eligible for garbage collection.

要自己观察行为,可以复制此文件的内容BigClass来找到4个对象.

To observe the behavior by yourself, you can copy the content of this file https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js in your console, then copy paste the example code. You will notice a memory increase in the task manager. When creating a heap dump in the Memory tab in the developer tools, you'll be able to find the 4 objects by typing BigClass in the search field.

然后,在控制台中键入subject = null;,然后创建一个新的堆转储.您会注意到这4个对象已消失.

After that, type subject = null; in the console, then create a new heap dump. You'll notice that the 4 objects have disappeared.

结论是,只要销毁Observable,就不会造成内存泄漏的真正风险,因为所有预订也将被销毁.有风险的Observables是永久性的(例如,使用fromEvent附加到全局DOM事件),并且具有指向需要销毁的对象的回调.

As a conclusion, as long as an Observable is destroyed, these is no real risk of a memory leak because all of the subscriptions will also be destroyed. The risky Observables are those who are permanent (e.g: attached to a global DOM event with fromEvent), and with callbacks referring to objects that need to be destroyed.

这篇关于如果可观察对象完成,是否需要取消订阅可观察对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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