+1内存分配20小时后,Angular Firebase应用程序崩溃 TLDR:增加侦听器数量是预期的行为,并将在垃圾回收时重置。 Firebase v7.5.0中已修复导致Firebase Auth中内存泄漏的错误,请参见#1121,检查package-lock.json以确认您使用的版本正确。如果不确定,请重新安装firebase软件包。

我发现使用AngularFireAuthModule中的'@angular/fire/auth';会导致内存泄漏,导致20小时后浏览器崩溃。

版本:

对于所有软件包,我都使用ncu -u今天更新的最新版本。

Angular Fire:"@angular/fire": "^5.2.3",

Firebase版本:"firebase": "^7.5.0"

如何复制:

我在StackBliztz editor上做了一个最低限度的可复制代码

这里是直接测试错误的链接StackBlizt test

症状:

您可以检查自己代码是否无效。它只是打印你好世界。但是,Angular App使用的JavaScript内存增加了 11 kb / s (Chrome任务管理器CRTL + ESC)。

在打开浏览器10个小时后,使用的内存大约达到 800 mb (内存占用大约是 1.6 Gb 的两倍!)

结果,浏览器内存不足,chrome标签页崩溃了。

在“性能”选项卡下使用chrome的内存配置文件进行了进一步研究之后,我清楚地注意到侦听器的数量每秒增加2,因此JS堆相应地增加。

+1内存分配20小时后,Angular Firebase应用程序崩溃
      
     TLDR:增加侦听器数量是预期的行为,并将在垃圾回收时重置。 Firebase v7.5.0中已修复导致Firebase Auth中内存泄漏的错误,请参见#1121,检查package-lock.json以确认您使用的版本正确。如果不确定,请重新安装firebase软件包。

导致内存泄漏的代码:

我发现使用AngularFireAuthModule模块会导致内存泄漏,无论它是注入到component构造函数中还是注入到service中。

import { Component } from '@angular/core';
import {AngularFireAuth} from '@angular/fire/auth';
import {AngularFirestore} from '@angular/fire/firestore';

@Component({
  selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'memoryleak';
  constructor(public auth: AngularFireAuth){

  }
}

问题

这可能是FirebaseAuth实施中的错误,我已经打开了Github问题,但我正在寻找此问题的解决方法。我迫切需要一个解决方案。我不介意即使跨选项卡的会话未同步。我不需要那个功能。我在某处读过

  

如果您不需要此功能,则Firebase V6   模块化工作将允许您切换到localStorage   具有用于检测交叉表的更改的存储事件,并且可能会   使您能够定义自己的存储接口。

如果这是唯一的解决方案,那么如何实现呢?

我只需要任何能够阻止这种不必要的监听器增加的解决方案,因为它会降低计算机的速度并导致我的应用程序崩溃。我的应用程序需要运行20多个小时,因此由于此问题,现在无法使用。我迫切需要一个解决方案。

cyf100765482 回答:+1内存分配20小时后,Angular Firebase应用程序崩溃 TLDR:增加侦听器数量是预期的行为,并将在垃圾回收时重置。 Firebase v7.5.0中已修复导致Firebase Auth中内存泄漏的错误,请参见#1121,检查package-lock.json以确认您使用的版本正确。如果不确定,请重新安装firebase软件包。

TLDR:增加侦听器数量是预期的行为,并将在垃圾回收时重置。 Firebase v7.5.0中已修复导致Firebase Auth中内存泄漏的错误,请参见#1121,检查package-lock.json以确认您使用的版本正确。如果不确定,请重新安装firebase软件包。

Firebase的早期版本是通过Promise链轮询IndexedDB的,这会导致内存泄漏,请参见JavaScript's Promise Leaks Memory

var repeat = function() {
  self.poll_ =
      goog.Timer.promise(fireauth.storage.IndexedDB.POLLING_DELAY_)
      .then(goog.bind(self.sync_,self))
      .then(function(keys) {
        // If keys modified,call listeners.
        if (keys.length > 0) {
          goog.array.forEach(
              self.storageListeners_,function(listener) {
                listener(keys);
              });
        }
      })
      .then(repeat)
      .thenCatch(function(error) {
        // Do not repeat if cancelled externally.
        if (error.message != fireauth.storage.IndexedDB.STOP_ERROR_) {
          repeat();
        }
      });
  return self.poll_;
};
repeat();

使用非递归函数调用在后续版本中修复:

var repeat = function() {
  self.pollTimerId_ = setTimeout(
      function() {
        self.poll_ = self.sync_()
            .then(function(keys) {
              // If keys modified,call listeners.
              if (keys.length > 0) {
                goog.array.forEach(
                    self.storageListeners_,function(listener) {
                      listener(keys);
                    });
              }
            })
            .then(function() {
              repeat();
            })
            .thenCatch(function(error) {
              if (error.message != fireauth.storage.IndexedDB.STOP_ERROR_) {
                repeat();
              }
            });
      },fireauth.storage.IndexedDB.POLLING_DELAY_);
};
repeat();


关于线性增加的侦听器数量:

期望侦听器数量线性增加,因为这是Firebase用来轮询IndexedDB的方法。但是,只要GC需要,侦听器将被删除。

阅读Issue 576302: Incorrectly showing memory (listeners xhr & load) leak

  

V8定期执行次要GC,这会导致那些小的堆大小下降。您实际上可以在火焰图上看到它们。但是,次要GC可能不会收集所有垃圾,这显然对于侦听器会发生。

     

工具栏按钮将调用能够收集侦听器的Major GC。

     

DevTools尝试不干扰正在运行的应用程序,因此它不会自行强制执行GC。


为确认分离的侦听器是否已被垃圾回收,我添加了此代码段以对JS堆施加压力,从而强制GC触发:

var x = ''
setInterval(function () {
  for (var i = 0; i < 10000; i++) {
    x += 'x'
  }
},1000)

Listeners are garbage collected

如您所见,触发GC时会定期删除分离的侦听器。



关于侦听器数量和内存泄漏的类似stackoverflow问题和GitHub问题:

  1. Listeners in Chrome dev tools' performance profiling results
  2. JavaScript listeners keep increasing
  3. Simple app causing a memory leak?
  4. $http 'GET' memory leak (NOT!)--number of listeners (AngularJS v.1.4.7/8)
本文链接:https://www.f2er.com/3008988.html

大家都在问