(simple plunkr demo here <http://plnkr.co/edit/1Adh2P65ZS8YHYJZhLMk>)
*SUMMARY:*
There is a leak using ng-repeat *after the 2nd wave* iterating over an
array of custom objects like this :
<div ng-repeat="d_sampleObject in mySampleObjects">
{{d_sampleObject.description}}
</div>
Memory profile reveals an extra 'd-sampleObject' left over and not
de-referenced. More details (via a controller and an injected service)
below. A simple demonstration also in the provided plunkr link. Any
thoughts and help greatly appreciated in advance!
*NOTE:* 'mySampleObjects' is an array of the following instances:
ml.MySampleObject = function (id) {
this.id = id;
this.description = 'this is object #:' + ' '+id;
}
*DETAILS:*
I have a custom object model that reflects the business domain objects that
we utilize in our AngularJS app. I have found that when I pass an instance
of one of my custom objects to ng-repeat, a reference is kept to it (I
think by Angular) and memory is not freed. This happens on the second
'wave' (click on 'refresh') of the ng-repeat as it iterates, again, over
its array of objects. This leak is exposed in my Profile tests (in Chrome)
. Here <http://plnkr.co/edit/1Adh2P65ZS8YHYJZhLMk> is a short example in
plunkr. Click on 'refresh' button once (or more) to see the extra
'd_sampleObject' object instance that is leaked (in Chrome Profile
Inpsection). Note, the 'd_sampleObject' name is only used when passed to
ng-repeat. I have included screenshots of the extra object instance
('d_sampleObject') that is being leaked further below. Why is there a leak
and how can it be avoided?
(Note, I have found if I don't iterate over my object collection (JS array)
thru an object but rather thru an primitive index ('integer'), there is no
leak. The leak seems to only happen when I use an object reference as a
result of ng-repeat iterations)
*SIMPLE 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="[email protected]"
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>
*SIMPLE 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 || {}));
*SIMPLE dataservice.js*
(function(ml) {
'use strict';
var serviceModule = angular.module('servicemodule',[]);
serviceModule.factory('dataservice', ['$rootScope', '$http',
function ($rootScope, $http) {
this.myObjectCollection = [];
var that = this;
this.redo = function () {
that.numRedos++;
// that.myObjectCollection = [];
that.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 || {}));
SCREENSHOT 1: (FIRST PAGE LOAD--there are 10 'mySampleObjects' created) [image:
SCREENSHOT 1: (FIRST PAGE LOAD--there are 10 'mySampleObjects' created)]
SCREENSHOT
2: (CLICKED ON REFRESH--there is an 11th mySampleObject created/leaked with
a reference to the instance name of 'd_sampleObject' passed to ng-repeat.)
[image:
(CLICKED ON REFRESH--there is an 11th mySampleObject created/leaked with a
reference to the instance name of 'd_sampleObject' passed to ng-repeat.)]
--
You received this message because you are subscribed to the Google Groups
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.