J'ai une application web écrite en AngularJS qui, en gros, des sondages d'une API à deux points de terminaison. De la sorte, chaque minute, il les sondages pour voir si il n'y a rien de nouveau.
J'ai découvert qu'il a une petite fuite de mémoire et j'ai fait de mon mieux pour le trouver, mais je ne suis pas en mesure de le faire. Dans le processus que j'ai réussi à réduire l'utilisation de la mémoire de mon application, ce qui est excellent.
Sans rien faire d'autre, tous les sondages, vous pouvez voir une pointe dans l'utilisation de la mémoire (c'est normal) et ensuite, il devrait tomber, mais il est toujours en augmentation. J'ai changé le nettoyage des tableaux à partir de []
de array.length = 0
et je pense que je suis sûr que les références ne pas persister, ce qui ne devrait pas être retenir de tout cela.
J'ai aussi essayé ceci: https://github.com/angular/angular.js/issues/1522
Mais sans un peu de chance...
Donc, c'est une comparaison entre deux tas:
La plupart de la fuite semble venir de (array) qui, si je l'ouvre, sont les tableaux retournés par l'analyse de l'appel d'API, mais je suis sûr qu'ils ne sont pas stockés:
C'est fondamentalement la structure:
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);
});
}
En gros, disons que j'ai un sellings
service donc, ce serait la valeur de l' service
variable.
Puis, dans l'écran principal:
$scope.$on('api.sellings', function(event, data) {
$scope.sellings.length = 0;
$scope.sellings = data;
});
Et la vue ne doit avoir un ngRepeat
qui le rend nécessaire. J'ai passé beaucoup de temps à essayer de comprendre par moi-même et je ne pouvais pas. Je sais que c'est un dur problème mais est-ce que quelqu'un a une idée sur la façon d'obtenir cela?
Edit 1 - Ajout de la Promesse de la vitrine:
C'est - makeRequest
ce qui est la fonction utilisée par les deux services:
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');
}
});
Si j'en commentaire l' $scope.$on('api.sellings')
partie, la fuite existe encore, mais il tombe à 1%.
PS: je suis en utilisant les dernières Angulaire de la version à jour
Edit 2 - Ouverture (array) de l'arbre dans une image
C'est comme tout ce qui c'est donc assez inutile à mon humble avis :(
Aussi, voici 4 tas de rapports de sorte que vous pouvez jouer vous-même:
https://www.dropbox.com/s/ys3fxyewgdanw5c/Heap.zip
Edit 3 - En réponse à @zeroflagL
Modification de la directive, n'ont pas d'impact sur la fuite bien que la fermeture de la partie, qui semble mieux depuis qu'il ne l'est pas jQuery cache des choses?
La directive ressemble maintenant à ceci
var destroy = function(){
if (cls){
stopObserving();
cls.destroy();
cls = null;
}
};
el.on('$destroy', destroy);
scope.$on('$destroy', destroy);
Pour moi, il me semble que ce qui se passe sur l' (array)
partie. Il y a aussi 3 nouveaux segments entre pollings.