Angular - 动态组件 - 编译器问题 - 内存泄漏?

时间:2017-10-27 22:12:43

标签: angular memory-leaks angular-compiler

我正在尝试创建一个动态组件。 Here是plunker中的样本。 http://embed.plnkr.co/EVFglgkp24hkRkpxrEGe/ 一切正常,但内存泄漏。

Here是github票证https://github.com/angular/angular/issues/19997

动态创建的组件正在被破坏,但是创建动态组件的组件不会被破坏。换句话说,编译动态组件的组件不会被破坏

在上面的示例中,如果我们在" Home"之间来回导航。和"动态页面"并使用chrome中的内存快照,您可以看到假设要销毁的组件仍然存在,如下所示。

enter image description here

出于测试目的,我甚至尝试评论波纹线,但问题仍然存在。

      let injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
      let ngMdlRef = ngMdlFac.create(injector);
      let cmpFactory = ngMdlRef.componentFactoryResolver.resolveComponentFactory(DynamicHtmlComponent);
      this.cmpRef = this.vcRef.createComponent(cmpFactory);

我打电话的那一刻

  

this.compiler.compileModuleAsync

创作者组件根本没有被破坏。直到那时没有问题。

你可以请别人帮忙吗?提前谢谢。

1 个答案:

答案 0 :(得分:4)

你是对的,内存泄漏的问题是由手动模块编译和实例化引起的。如果您查看MyCreatorComponent的保留者,可以看到函数DynamicHtmlComponentDynamicModule通过上下文保留对父MyCreatorComponent函数的引用。

enter image description here

这些是与GC根目录距离最短的对象,因此它们很可能是导致内存泄漏的对象。问题是他们为什么不被删除?答案是Angular会严重缓存它创建的所有内容,并且它也会在您的情况下发生。通过快速浏览,我发现了至少两个保留引用的缓存。

第一

export class JitCompiler {
  private _compiledHostTemplateCache = new Map<Type, CompiledTemplate>();

当您致电this.compiler.compileModuleAsync(DynamicModule) Angular时,将CompiledTemplate密钥DynamicHtmlComponent添加到此缓存中,并且永远不会将其清除。

第二

const _tokenKeyCache = new Map<any, string>();

当您致电var ngMdlRef = ngMdlFac.create(...) Angular将DynamicHtmlComponentFactory添加到此缓存中时,永远不会将其删除。

请注意,这些缓存为Maps,而不是WeakMaps,因此只要没有对.delete()的显式调用,就会保留对象。