简体   繁体   English

Angular:垃圾收集组件

[英]Angular: Garbage collection Components

I try to understand how the GabageCollector works after a component was destroyed.我试图了解 GabageCollector 在组件被销毁后是如何工作的。 I have the following case:我有以下情况:

AppComponent:应用组件:

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

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

  nop(){

  }
}

AppHTML:应用HTML:

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

EMPTY FN空FN

TestComponent:测试组件:

export class TestComponent implements OnInit {

  @Output()
  public close = new EventEmitter()

  @Input()
  id;

  constructor() { }

  ngOnInit() {
  }

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

}

TestHTML:测试HTML:

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

Now when i start the app and take a heap-snapshot i see the right amount of objects in memory:现在,当我启动应用程序并拍摄堆快照时,我会在内存中看到正确数量的对象: 在此处输入图片说明

Then i remove a component by clicking the close-button and take a new snapshot:然后我通过单击关闭按钮删除一个组件并拍摄新快照: 在此处输入图片说明

To my surprise, there are still two objects?令我惊讶的是,还有两个对象? And now additionally the strange thing is, if i click the "EMPTY FN" button, which does nothing (empty-function on app-component), the next snapshot looks like this:现在另外奇怪的是,如果我点击“EMPTY FN”按钮,它什么都不做(app-component 上的空函数),下一个快照看起来像这样: 在此处输入图片说明

I have a few questions about this topic:我有几个关于这个话题的问题:

  • How the GC works in detail? GC 的详细工作原理是什么? For my special case i think the GC cant free the memory because there is still a reference to that object.对于我的特殊情况,我认为 GC 无法释放内存,因为仍然存在对该对象的引用。 How to find out where this reference lives?如何找出此引用所在的位置?
  • Why the GC isnt invoked after the first component is removed, but called if the empty function is called afterwards?为什么在删除第一个组件后不调用 GC,而是在之后调用空函数时调用?
  • Do i have to care about this "dead" object (assume the testcomponent subscribes to a few observables but unsubscribe them properly via async-pipe or in ngOnDestroy) ?我是否必须关心这个“死”对象(假设 testcomponent 订阅了一些 observables 但通过 async-pipe 或在 ngOnDestroy 中正确取消订阅)?

It seems Chrome keeps one instance in memory for ngFor. Chrome 似乎在内存中为 ngFor 保留了一个实例。 Memory leak isn't as severe as it would seem.内存泄漏并不像看起来那么严重。

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

By comparing snapshots on Chrome:通过比较 Chrome 上的快照:

  • clicking the last "close" it will remove the element from DOM but keep that in the memory for some odd reason.单击最后一个“关闭”,它将从 DOM 中删除该元素,但出于某种奇怪的原因将其保留在内存中。
  • clicking the first "close" it will remove the element from DOM and no memory leak happens.单击第一个“关闭”它将从 DOM 中删除元素并且不会发生内存泄漏。
  • removing the last TestComponent by clicking "close" will leave one TestComponent in the memory.通过单击“关闭”删除最后一个 TestComponent 将在内存中留下一个 TestComponent。
  • The TestComponent count in the memory never exceeds one over the items in the DOM.内存中的 TestComponent 计数永远不会超过 DOM 中的项数。
  • When I add new TestComponents the extra item is cleaned up & there is no detectable memory leak.当我添加新的 TestComponents 时,额外的项目被清除并且没有可检测的内存泄漏。

Code for reference: https://stackblitz.com/edit/angular-garbage-collection-components参考代码: https : //stackblitz.com/edit/angular-garbage-collection-components

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM