Angular: Компоненты для сбора мусора - PullRequest
0 голосов
/ 27 февраля 2020

Я пытаюсь понять, как работает GabageCollector после уничтожения компонента. У меня есть следующий случай:

AppComponent:

export class AppComponent {
  testCompoments = [1,2];

  removeOne(id){
    this.testCompoments.pop()
  }

  nop(){

  }
}

App HTML:

<ng-container *ngFor="let t of testCompoments">
  <app-test [id]="t" (close)="removeOne($event)"></app-test>
</ng-container>
<br>

EMPTY FN

TestComponent:

export class TestComponent implements OnInit {

  @Output()
  public close = new EventEmitter()

  @Input()
  id;

  constructor() { }

  ngOnInit() {
  }

  closeClick(){
    this.close.emit(this.id)
  }

}

Тест HTML:

<p>{{id}}</p>
<button (click)="closeClick()">close</button>

Теперь, когда я запускаю приложение и делаю снимок кучи, я вижу правильное количество объектов в памяти: enter image description here

Затем я удаляю компонент, нажимая кнопку закрытия и делаю новый снимок: enter image description here

К моему удивлению, есть еще два объекта? И теперь, кроме того, странно то, что если я нажимаю кнопку «ПУСТО FN», которая ничего не делает (пустая функция для компонента приложения), следующий снимок выглядит следующим образом: enter image description here

У меня есть несколько вопросов об этой топи c:

  • Как G C работает в деталях? Для моего особого случая я думаю, что G C не может освободить память, потому что есть ссылка на этот объект. Как узнать, где находится эта ссылка?
  • Почему G C не вызывается после удаления первого компонента, но вызывается, если потом вызывается пустая функция?
  • Должен ли я заботиться об этом «мертвом» объекте (предположим, что тестовый компонент подписывается на несколько наблюдаемых, но отписывается от них должным образом через asyn c -pipe или в ngOnDestroy)?

1 Ответ

1 голос
/ 03 марта 2020

Кажется, Chrome хранит один экземпляр в памяти для ngFor. Утечка памяти не так серьезна, как кажется.

https://angular-garbage-collection-components.stackblitz.io/

Сравнение снимков на Chrome:

  • Если щелкнуть последний «закрыть», он удалит элемент из DOM, но по какой-то странной причине он останется в памяти.
  • Если щелкнуть первый «закрыть», он удалит элемент из DOM, и утечка памяти не произойдет.
  • удаление последнего TestComponent нажатием кнопки «закрыть» оставит один TestComponent в памяти.
  • Количество TestComponent в памяти никогда не превышает один над элементами в DOM.
  • Когда я добавляю новые TestComponents, дополнительный элемент очищается и не обнаруживается утечка памяти.

Код для справки: https://stackblitz.com/edit/angular-garbage-collection-components

...