Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 角度+;摩卡内存泄漏_Angularjs_Memory Leaks_Mocha.js - Fatal编程技术网

Angularjs 角度+;摩卡内存泄漏

Angularjs 角度+;摩卡内存泄漏,angularjs,memory-leaks,mocha.js,Angularjs,Memory Leaks,Mocha.js,在运行整个测试套件时,我遇到以下错误: 超出了2000ms的超时时间。确保在此测试中调用了done()回调。 经过调查,我发现是内存泄漏问题。查看一些堆分析快照,对象似乎仍然被引用,并没有被收集 有人知道一个可以阻止它发生的解决方案吗?有一些选择,比如检查我的每一个1000ish规格,并在每个规格之后添加,,以进行一些清理,但这似乎需要做很多工作 下面是我的大多数测试的示例布局 describe('MyClassCtrl', function() { var $httpBackend, $

在运行整个测试套件时,我遇到以下错误:

超出了2000ms的超时时间。确保在此测试中调用了done()回调。

经过调查,我发现是内存泄漏问题。查看一些堆分析快照,对象似乎仍然被引用,并没有被收集

有人知道一个可以阻止它发生的解决方案吗?有一些选择,比如检查我的每一个1000ish规格,并在每个规格之后添加
,以进行一些清理,但这似乎需要做很多工作

下面是我的大多数测试的示例布局

describe('MyClassCtrl', function() {

  var $httpBackend, $rootScope, ctrl;
  ctrl = $rootScope = $httpBackend = null;

  beforeEach(function() {
    module('myApp');
    inject(function($controller, $rootScope, _$httpBackend_, $stateParams) {
      var $scope;
      $stateParams.id = 1;
      $httpBackend = _$httpBackend_;
      $scope = $rootScope.$new();
      ctrl = $controller('MyClassCtrl', {
        $scope: $scope
      });
    });
  });

  describe('#_getMyList', function() {
    beforeEach(function() {
      $httpBackend.expectGET("/my/app/url").respond({
        my_list: [1, 2, 3]
      });
      ctrl._getMyList();
      $httpBackend.flush();
    });

    it('does this', function() {
      expect(ctrl.my_list).to.eql([1, 2, 3]);
    });
  });
});
以下是一些分析截图:

更新

我可以通过简单地将我的
it
包装成一个循环来触发内存泄漏

e、 g:

(i=0;i<200;i++)的
{
它('做这个',函数(){
expect(ctrl.my_list).to.eql([1,2,3]);
});
}
在我的测试中,我设置了容器对象中的所有对象,并在每次
之后清理它(就像解决方案一样),但没有运气。Chrome的开发时间线工具上的内存分配仍在不断增加


谢谢

我没有看到你清理模拟的http后端。我不知道它是如何工作的,但我希望您的所有请求和响应都存储在内存中。这将导致它逐渐增加,一次又一次的测试

如果这是使用Sinon,我希望您在测试之前创建一个存根/间谍,然后将其清除(或者在沙箱中运行)


尝试在运行测试之前和之后拍摄堆快照,并区分快照以查找哪些对象的数量不断增加。

不确定,但这可能与测试相关。确保将本地摩卡更新到
2.4.5
或更高版本,以获得修复并尝试运行测试。

在单元测试中,ui路由器似乎会泄漏内存。我在应用程序的运行块中添加了以下代码:

$rootScope.$on('$destroy', function() {
    var clearAllMembers = function(obj, depth) { // prevent infinite recursion because of circular references
        depth = depth || 0;
        if (depth > 10) {
            return;
        }
        for (var i in obj) {
            if (obj.hasOwnProperty(i)) {
                if (typeof(obj[i]) == 'object') {
                    clearAllMembers(obj[i], ++depth);
                }
                if (obj) {
                    if (obj[i] && (obj[i] instanceof Array) && obj[i].length) {
                        obj[i].splice(0);
                    }
                    delete obj[i];
                }
            }
        }
    }

    setTimeout(function() {
        clearAllMembers($stateRegistry); // ui-router 1.0+
        clearAllMembers($urlRouter);
        clearAllMembers($urlService); // ui-router 1.0+
        clearAllMembers($state);
    });
});

单元测试中的内存消耗是原来的7-8倍(我有大约350个状态)

是因果报应还是摩卡帮你收集日志数据?当测试结果存储在内存中时,可能会出现这种情况,请尝试在配置文件中设置
logLevel:LOG\u DISABLE
,以查看是否存在任何错误difference@maurycy说得好!不幸的是,将日志级别设置为
log\u DISABLE
似乎没有帮助。您是否在覆盖范围内运行它?坦率地说,在每个套件文件之后,内存应该是干净的,这很有趣!我如何确切地检查是否已启用该功能?目前,我的karma配置只有
报告者:['spec']
,但即使删除它也无济于事。如果你不知道,那么你很可能不会运行覆盖范围,因为你需要明确设置它。当您在浏览器中运行应用程序时,是否也会发生同样的情况,或者这只是单元测试的问题?
$rootScope.$on('$destroy', function() {
    var clearAllMembers = function(obj, depth) { // prevent infinite recursion because of circular references
        depth = depth || 0;
        if (depth > 10) {
            return;
        }
        for (var i in obj) {
            if (obj.hasOwnProperty(i)) {
                if (typeof(obj[i]) == 'object') {
                    clearAllMembers(obj[i], ++depth);
                }
                if (obj) {
                    if (obj[i] && (obj[i] instanceof Array) && obj[i].length) {
                        obj[i].splice(0);
                    }
                    delete obj[i];
                }
            }
        }
    }

    setTimeout(function() {
        clearAllMembers($stateRegistry); // ui-router 1.0+
        clearAllMembers($urlRouter);
        clearAllMembers($urlService); // ui-router 1.0+
        clearAllMembers($state);
    });
});