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