【发布时间】:2025-12-20 05:45:06
【问题描述】:
(简单的 plunkr 演示 here)
总结:
使用 ng-repeat 在第二波之后在自定义对象的“数组”上迭代存在泄漏,如下所示:
<div ng-repeat="d_sampleObject in mySampleObjects">
{{d_sampleObject.description}}
</div>
内存配置文件显示了一个多余的“d_sampleObject”,没有被取消引用。更多细节(通过控制器和注入服务)如下。提供的 plunkr 链接中也有一个简单的演示。任何想法和帮助都提前非常感谢!
注意:“mySampleObjects”是以下实例的数组:
ml.MySampleObject = function (id) {
this.id = id;
this.description = 'this is object #:' + ' '+id;
}
详情:
我有一个自定义对象模型,它反映了我们在 AngularJS 应用程序中使用的业务领域对象。我发现当我将我的一个自定义对象的实例传递给 ng-repeat 时,会保留对它的引用(我认为是 Angular)并且不会释放内存。这发生在 ng-repeat 的第二个“wave”(单击“refresh”)上,因为它再次迭代其对象数组。此泄漏在我的个人资料测试(在 Chrome 中)中暴露。 Here 是 plunkr 中的一个简短示例。单击“刷新”按钮一次(或多次)以查看泄漏的额外“d_sampleObject”对象实例(在 Chrome 配置文件检查中)。请注意,“d_sampleObject”名称仅在传递给 ng-repeat 时使用。我已经包含了在下面进一步泄漏的额外对象实例('d_sampleObject')的屏幕截图。为什么会出现泄漏,如何避免?
(注意,我发现如果我不通过对象而是通过原始索引(“整数”)迭代我的对象集合(JS 数组),则没有泄漏。泄漏似乎只发生在我使用对象引用作为 ng-repeat 迭代的结果)
简单的 HTML:
<!DOCTYPE html>
<html ng-app="memoryleak">
<head>
<meta charset="utf-8" />
<title>Memory Leak Test</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.13/angular.min.js" data-semver="1.3.13"></script>
<script src="app.js"></script>
<script src="dataservice.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="d_sampleObject in mySampleObjects">
{{d_sampleObject.description}}
</div>
<br>
<button ng-click="redo()">Number of refreshes: {{numRedos}}!</button>
</body>
</html>
简单的 APP.JS
(function(ml) {
var app = angular.module('memoryleak',['servicemodule']);
app.controller('MainCtrl', ['$scope', 'dataservice', function($scope, dataservice) {
$scope.redo = function () {
$scope.numRedos++;
$scope.mySampleObjects = dataservice.myObjectCollection;
dataservice.redo();
}
$scope.redo();
}]);
}(window.MEMLEAK = window.MEMLEAK || {}));
简单的数据服务.js
(function(ml) {
'use strict';
var serviceModule = angular.module('servicemodule',[]);
serviceModule.factory('dataservice', ['$rootScope', '$http',
function ($rootScope, $http) {
this.myObjectCollection = [];
this.redo = function () {
this.numRedos++;
// that.myObjectCollection = [];
this.myObjectCollection.length = 0;
for (var i = 0; i < 10; i++) {
var sampleObject = new ml.MySampleObject(i);
that.myObjectCollection.push(sampleObject);
}
sampleObject=null;
}
ml.MySampleObject = function (id) {
this.id = id;
this.description = 'this is object #:' + ' '+id;
}
return this; //return the entire service to make methods accessible to dependents
}]);
}(window.MEMLEAK = window.MEMLEAK || {}));
屏幕截图 1:(加载第一页——创建了 10 个“mySampleObjects”) 屏幕截图 2:(点击刷新——创建/泄露了第 11 个 mySampleObject,并引用了传递给 ng-repeat 的“d_sampleObject”的实例名称。)
【问题讨论】:
标签: javascript memory-leaks angularjs-ng-repeat