如何捕获Angular应用程序中的内存泄漏?

 mobiledu2402852357 发布于 2023-02-09 15:01

我有一个用AngularJS编写的webapp,它基本上将API轮询到两个端点.所以,它每分钟都会进行一次调查,看看是否有新的东西.

我发现它有一个小的内存泄漏,我已尽力找到它,但我无法做到.在这个过程中,我设法减少了我的应用程序的内存使用量,这很棒.

在没有做任何其他事情的情况下,每次调查你都可以看到内存使用量的增长(这是正常的)然后它应该下降,但它总是在增加.我从改变阵列的清洗[]array.length = 0,我想我敢肯定,引用不持续存在,因此它不应该被保留的任何现象.

我也试过这个:https://github.com/angular/angular.js/issues/1522

但没有运气......

所以,这是两个堆之间的比较:

内存堆

大多数泄漏似乎来自(数组),如果我打开,它是通过解析API调用返回的数组,但我确定它们没有被存储:

这基本上是结构:

poll: function(service) {
  var self = this;
  log('Polling for %s', service);

  this[service].get().then(function(response) {
    if (!response) {
      return;
    }

    var interval = response.headers ? (parseInt(response.headers('X-Poll-Interval'), 10) || 60) : 60;

    services[service].timeout = setTimeout(function(){
      $rootScope.$apply(function(){
        self.poll(service);
      });
    }, interval * 1000);

    services[service].lastRead = new Date();
    $rootScope.$broadcast('api.'+service, response.data);
  });
}

基本上,假设我有一个sellings服务,那就是service变量的值.

然后,在主视图中:

$scope.$on('api.sellings', function(event, data) {
  $scope.sellings.length = 0;
  $scope.sellings = data;
});

并且视图确实具有ngRepeat根据需要呈现的视图.我花了很多时间试图自己解决这个问题,但事实并非如此.我知道这是一个很难的问题但是,有没有人知道如何追踪这个问题?

编辑1 - 添加承诺展示:

这是makeRequest两个服务使用的功能:

return $http(options).then(function(response) {
    if (response.data.message) {
      log('api.error', response.data);
    }

    if (response.data.message == 'Server Error') {    
      return $q.reject();
    }

    if (response.data.message == 'Bad credentials' || response.data.message == 'Maximum number of login attempts exceeded') {
      $rootScope.$broadcast('api.unauthorized');
      return $q.reject();
    }

    return response;
    }, function(response) {
    if (response.status == 401 || response.status == 403) {
      $rootScope.$broadcast('api.unauthorized');
    }
});

如果我注释掉$scope.$on('api.sellings')部件,泄漏仍然存在,但下降到1%.

PS:我使用最新的Angular版本

编辑2 - 图像中的打开(数组)树

在此输入图像描述

这就是一切,所以它是无用的imho :(

此外,这里有4个堆报告,您可以自己玩:

https://www.dropbox.com/s/ys3fxyewgdanw5c/Heap.zip

编辑3 - 响应@zeroflagL

编辑指令,对泄漏没有任何影响,虽然封闭部分似乎更好,因为它没有显示jQuery缓存的东西?

没有泄漏?

该指令现在看起来像这样

var destroy = function(){
  if (cls){
    stopObserving();
    cls.destroy();
    cls = null;
  }
};

el.on('$destroy', destroy);
scope.$on('$destroy', destroy);

对我来说,似乎正在发生的事情就是这一点(array).在民意调查之间还有3个新的堆.

1 个回答
  • 答案就是缓存.

    堆快照分析

    我不知道它是什么,但这件事情增长了.它似乎与jQuery有关.也许这是jQuery元素缓存.你是否有机会在每次服务电话后在一个或多个元素上应用jQuery插件?

    更新

    问题是添加了HTML元素,使用jQuery进行处理(例如通过popbox插件),但是从未删除过或者没有使用jQuery删除.在这种情况下处理意味着添加事件处理程序之类的东西.缓存对象中的条目(无论它是什么)只有在jQuery知道元素已被删除时才会被删除.这就是必须使用jQuery删除元素.

    更新2

    目前尚不清楚为什么缓存中的这些条目没有被删除,因为当它被包含时,angular应该使用jQuery.但它们是通过评论中提到的插件添加的,并包含事件处理程序和数据.AFAIK Antonio更改了插件代码以取消绑定事件处理程序并删除插件destroy()方法中的数据.这最终消除了内存泄漏.

    2023-02-09 15:05 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有