Description du problème:
Un problème de fuite de mémoire a été trouvé lors d'une recherche, comme le montre l'image :
Après 15 recherches, la mémoire est passée de 15 Mo à 18 Mo, ce qui est assez grave.
Dépannage
Après débogage et analyse, l'emplacement approximatif du problème a finalement été localisé :
function searchData() { console.log('search'); var sc = {}; // 获取类名为fui-form下的所有mini控件,遍历将搜索条件形成下面的格式 // { // "控件id":"控件值" // } mini.getChildControls(document.getElementsByClassName('fui-form')[0]).forEach(function (item) { sc[item.id] = item.getValue(); }); console.log('搜索条件' + JSON.stringify(sc, 0, 4)); grid.load(); }
Commentez tout saufgrid.load()
, et les résultats d'une recherche 0, 1 et 10 fois sont les suivants :
On peut voir qu'à mesure que le nombre de recherches de mémoire augmente, la mémoire n'augmente pas et il n'y a pas de problème de fuite de mémoire.
Ensuite, j'ai pensé que c'étaitconsole
的问题,注释掉两个console
, et les résultats sont les suivants (toujours recherché 0 fois, 1 fois, 10 fois) :
Le problème est toujours le même. On voit qu'il ne s'agit pas d'un problème avec la console. En fait, il est impossible d'y penser. Cependant, lors du dépannage, il s'agissait essentiellement d'un traitement d'urgence.
Ce qui suit peut essentiellement localiser le problème causé par cette section.
var sc = {}; mini.getChildControls(document.getElementsByClassName('fui-form')[0]).forEach(function (item) { sc[item.id] = item.getValue(); });
Pour l'analyse, ce qui précède peut être divisé en deux parties : l'obtention du tableau de contrôle et l'exploration des données organisationnelles
var sc = {}; var controls = mini.getChildControls(document.getElementsByClassName('fui-form')[0]); controls.forEach(function (item) { sc[item.id] = item.getValue(); });
Après avoir divisé l'acquisition et le parcours, puis testé, le problème n'existe plus, comme le montre l'image :
Dernière question
Deux façons d'obtenir le contrôle et de le parcourir dans la fonction
Première méthode d'écriture :
// 获取并遍历 mini.getChildControls(document.getElementsByClassName('fui-form')[0]).forEach(function (item) { sc[item.id] = item.getValue(); });
Méthode d'écriture deux :
// 获取控件 var controls = mini.getChildControls(document.getElementsByClassName('fui-form')[0]); // 遍历 controls.forEach(function (item) { sc[item.id] = item.getValue(); });
Pourquoi y a-t-il une fuite de mémoire dans le premier cas, mais pas dans le second cas ?
Ce n'est pas forcément une fuite de mémoire, il est aussi possible que le gc n'ait pas recyclé le dom. Dans la première manière d'écrire, la déclaration n'est pas terminée et tous les doms doivent être conservés référencés. terminé, et il est possible que le gc ait recyclé le dom. Node, simplement en fonction du nombre et de l'heure de vos tests, vous ne pouvez pas déterminer si la première façon d'écrire est vraie et le dom ne sera pas recyclé à la fin.
Vous devez comparer les données de 15,9 et 15,6. Il y a une comparaison dans le coin supérieur gauche du tableau, qui est la partie récapitulative de votre image. Comparez ce qu'il y a de plus en 15,9 et 15,6. Cliquez pour voir la partie jaune. représente les références continues. Si la mémoire ne diminue toujours pas après l'avoir exécuté plusieurs fois, cela peut être considéré comme une fuite de mémoire.