Управление памятью (утечки?) В Angular и RxJS - PullRequest
0 голосов
/ 13 июня 2018

Я пытался рассуждать о продолжительности жизни абонента в RxJS.То есть мы все знаем, что нам нужно отписаться от наблюдаемого, верно?Но вопрос таков: почему?

Я занимаюсь разработкой большого приложения на основе Angular, поэтому я не могу поделиться своим кодом, но постараюсь дать вам контекст моего эксперимента по мышлению.Допустим, у нас есть следующий компонент:

class Comp extends Component {
    public o$;
    constructor(private store$: Store) {}
    ngOnInit() {
        this.o$ = this.store$.pipe(select(...), map(...));
        this.o$.subscribe(function() {
            this.whateverFromComponent(); // Let's tie this to component via closure
        });
    }
}

Таким образом, мы могли бы написать что-то вроде this.o$.pipe(takeUntil(this.onDestroy$)), но я использую собственный Angular Router, поэтому, вероятно, когда я изменяю подстраницу, класс Compэкземпляр удален, а единственная ссылка на o$ удалена, поэтому единственная ссылка на обратный вызов удалена, и мы все сделали?

Но, похоже, это не тот случай: когда компонент удаляетсяиз DOM и был вызван onDestroy, я ожидаю, что экземпляр comp тоже удален, но явно не удален, так как в противном случае нам не нужно было бы отписываться от наблюдаемых.

Итак, я началдумать, что Angular создает экземпляр компонента один раз, и когда он не используется, ссылки на экземпляр класса компонента не удаляются, а сохраняются для дальнейшего использования.Но, похоже, это тоже не так, поскольку console.log, помещенный в конструктор, вызывается каждый раз, когда компонент отображается на странице.

Хорошо, так что на данный момент я знаю, что экземпляр компонента не удаляетсяиз памяти при удалении из DOM, так как подписка вызывается в любом случае.И экземпляр компонента создается каждый раз, когда он помещается в DOM.Waaaat?

Я запустил DevTools, сделал снимок памяти и отфильтровал имя класса компонента.И действительно, кажется, что каждый раз, когда компонент отображается на странице, создается новый экземпляр.Так что я нашел n refs для компонента, хотя только один из них был необходим.

Я начал копаться, и на экземпляры устаревших компонентов ссылались из какой-то подписки, которая, кажется, пришла от Angular Router.

Не могли бы вы помочь мне выяснить, когда (если вообще когда-либо) экземпляр класса Component удаляется из памяти?И почему подписка сохраняется?

1 Ответ

0 голосов
/ 13 июня 2018

Пока поток активен, ему, очевидно, нужна ссылка на все подписки.В противном случае он не мог бы выдавать значения подписчикам.Однако, когда поток завершен, это уже не так.

В вашем примере store$ (скорее всего) никогда не завершится, поэтому вам нужно отписаться.В противном случае как подписка, так и поток останутся живыми (хотя имя store$ подразумевает, что этот конкретный поток, вероятно, будет жить так же долго, как и приложение).

Когда экземпляр компонента удаляется из памяти, зависит отсборщик мусора и содержит ли какой-либо код ссылку на экземпляр.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...