【问题标题】:Angular - Dynamic Component - Compiler Issue - Memory Leak?Angular - 动态组件 - 编译器问题 - 内存泄漏?
【发布时间】:2018-04-09 14:14:22
【问题描述】:

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

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

动态创建的组件被销毁,但创建动态组件的组件没有被销毁。换句话说,编译动态组件的组件没有被销毁

在上面的示例中,如果我们在“主页”和“动态页面”之间来回导航并在 chrome 中拍摄内存快照,您可以看到假定被销毁的组件仍然存在,如下图所示。

出于测试目的,我什至尝试评论以下行,但问题仍然存在。

      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

创建者组件根本没有被销毁。在那之前没有问题。

你能请人帮忙吗?提前谢谢你。

【问题讨论】:

    标签: angular memory-leaks angular-compiler


    【解决方案1】:

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

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

    首先

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

    当您调用 this.compiler.compileModuleAsync(DynamicModule) 时,Angular 会将带有键 DynamicHtmlComponentCompiledTemplate 添加到此缓存中,并且永远不会清除它。

    第二

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

    当您调用 var ngMdlRef = ngMdlFac.create(...) 时,Angular 会将 DynamicHtmlComponentFactory 添加到此缓存中并且永远不会删除它。

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

    【讨论】:

    • 虽然我们可以运行compiler.clearCache 来清除compiledHostTemplateCache 和编译器中缓存的其他内容,但我们无法清除tokenKeyCache
    • @yurzui,是的,这只是我找到的两个。我认为还有其他人
    • Angular 每次执行编译时都会在 tokenKeyCache 中为提供者添加所有标记,我认为这是因为该编译器应该只运行一次
    • 另外我们需要启用 prod 模式
    • @yurzui,是的,看来我们无法通过这种方法避免内存泄漏
    猜你喜欢
    • 1970-01-01
    • 2016-07-28
    相关资源
    最近更新 更多