Maison > Article > interface Web > Comprendre le mécanisme de récupération de place, les fuites de mémoire et les fermetures de la série JS (3) avec un seul morceau de papier
La colonne
javascript vous présente le mécanisme de récupération de place, les fuites de mémoire et le contenu de fermeture. Jetons un coup d'œil au banc de fin rapide.
Écrit au début : Il s'agit d'une série que je suis sur le point de commencer à écrire dans la colonne javascript, principalement dans la framework A l'époque, même si j'utilise un framework pour le travail, pour les entretiens et l'avancement technique, les connaissances de base de JS sont la cerise sur le gâteau, et c'est aussi une connaissance que je dois apprendre même si ce n'est pas le cas. Il faut en savoir beaucoup sur les voitures pour conduire une voiture, il suffit de maîtriser les usages courants des voitures. Mais si vous connaissez les voitures, vous pouvez mieux conduire, et par la même occasion. Bien sûr, un article ne parlera pas uniquement d'un seul point de connaissance. Généralement, les points de connaissance associés seront connectés en série. Tout en enregistrant votre propre apprentissage, vous partagerez votre propre apprentissage et vous encouragerez mutuellement ! Si vous le pouvez, s'il vous plaît, donnez-moi un like Votre like me fera également travailler plus dur pour mettre à jour !
Le blog précédent explique principalement l'allocation et l'utilisation de la mémoire (mémoire de pile et mémoire de tas, copie profonde et copie superficielle, bien sûr, retour). la mémoire inutilisée revient à supprimer les logiciels inutilisés de votre téléphone en arrière-plan. Cela peut améliorer la vitesse de fonctionnement de votre téléphone. Sinon, s'il y a de plus en plus de mémoire, il restera bloqué tôt ou tard JS
Il en va de même pour <.>.
De temps en temps, le JS
éboueur de « patrouillera » les variables, tout comme les gardes de sécurité patrouillent dans le parc, laissant les personnes non pertinentes partir rapidement. Lorsqu'une variable n'est plus nécessaire, elle libère l'espace mémoire occupé par la variable. Ce processus est appelé Garbage Collection
JS
L'algorithme de garbage collection est divisé en deux types, méthode de comptage de références et méthode d'effacement des marques
La méthode de comptage de références est l'algorithme de collecte des ordures le plus rudimentaire et a été éliminée par les navigateurs modernes. Avant d'apprendre la méthode de comptage de références, vous devez d'abord avoir une certaine notion de la référence . Vous pouvez la considérer comme une description de l'adresse mémoire pointée par la variable actuelle, qui est quelque peu similaire à la. pointeur mémoire du type de données de référence JS. Pour comprendre le concept, regardons d'abord une ligne de code :
var obj={name:'jack'};复制代码
Lorsque nous attribuons une valeur à obj
, nous créons en fait une référence pointant vers la variable, avec un nombre de références de 1,Sous le mécanisme de comptage de références, chaque valeur en mémoire correspondra à un nombre de références
à obj
, cette variable devient Un morceau de mémoire inutile, alors à ce moment, le décompte de références de null
deviendra obj
0, et il sera recyclé par le garbage collector, c'est-à-dire le l'espace mémoire occupé par sera libéréobj
fuite de mémoire Regardons d'abord un morceau de code et les résultats en cours d'exécution :
function changeName(){ var obj1={}; var obj2={}; obj1.target=obj2; obj2.target=obj1; obj1.age=15; console.log(obj1.target); console.log(obj2.target); } changeName();复制代码<.> font référence l'un à l'autre, car lorsque
obj1.target
est modifié, obj2.target
et obj1.age
sont également affectés à en même temps, et le décompte de références vers lequel ils pointent est cohérent obj1.target.age
Lorsque la fonction termine son exécution, obj2.target.age
et sont toujours bien vivants, car le décompte de références de obj1
et obj2
est toujours obj1.target
1obj2.target
après l'exécution. , il est clair que la fonction a été exécutée, mais ce genre de déchets existe toujours s'il y a trop de fonctions de ce type, Les fuites de mémoire seront inévitables.
, il est principalement divisé en deux étapes, étape de marquage et étape de nettoyage :
Le garbage collector partira de l'objet racine (objet Window) et analysera tous les objets accessibles. C'est ce qu'on appelle
accessible<.>
Phase claire Lors de l'analyse, les objets qui ne peuvent pas être atteints par l'objet racine (现在再来看下上面的代码
function changeName(){ var obj1={}; var obj2={}; obj1.target=obj2; obj2.target=obj1; obj1.age=15; console.log(obj1.target); console.log(obj2.target); } changeName();复制代码
在函数执行完毕之后,函数的声明周期结束,那么现在,从 Window对象
出发, obj1
和 obj2
都会被垃圾收集器标记为不可抵达,这样子的情况下,互相引用的情况也会迎刃而解。
该释放的内存垃圾没有被释放,依然霸占着原有的内存不松手,造成系统内存的浪费,导致性能恶化,系统崩溃等严重后果,这就是所谓的内存泄漏
闭包是指有权访问另一个函数作用域中的变量的函数。至于为什么有权访问,主要是因为作用域嵌套作用域,也就是所谓的作用域链,关于作用域链不清楚的可以看我的第一篇博客一文搞懂JS系列(一)之编译原理,作用域,作用域链,变量提升,暂时性死区,就是因为作用域链的存在,所以内部函数才可以访问外部函数中定义的变量 ,作用域链是向外不向内的,探出头去,向外查找,而不是看着锅里,所以外部函数是无法访问内部函数定义的变量的。并且,还有一个特性就是将闭包内的变量始终保持在内存中。
前面的作用域向外不向内,这里就不再做过多解释了,我们主要来看我后面说的特性,那就是闭包内的变量始终保存在内存中
来看一下阮一峰教程当中的一个例子
function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ console.log(n); } return f2; } var result=f1(); //等同于return f2(); result(); // 999 nAdd(); result(); // 1000 nAdd(); result(); // 1000复制代码
从输出结果就可以看得出来,这个变量 n
就一直保存在内存中,那么,为什么会这样子呢,我们现在就来逐步地分析代码
① 首先 f1()
作为 f2()
的父函数,根据作用域链的规则, nAdd()
方法以及 f2()
方法中可以正常访问到 n
的值
② f2()
被赋予了一个全局变量,可能这里大家就会开始产生疑惑了,这个 f2()
不是好好地定义在了 f1()
函数中吗,这不是扯淡吗,那么,先看下面的这句 var result=f1();
,这个 result
很明显是被赋予了一个全局变量,这应该是没有任何争议的,那么,接着来看这个 f1()
,可以看到最后,是一句 return f2;
,看到这里,想必大家也已经想明白了,这个 f2()
被赋予了一个全局变量
③ 已经明白了上面的这一点以后,根据上面垃圾回收机制所提及到的标记清除法,这个 f2()
始终是可以被根对象 Window
访问到的,所以 f2 将始终存在于内存之中,而 f2 是依赖于 f1 ,因此 f1 也将始终存在于内存当中,那么, n
的值也就自然始终存在于内存当中啦
④ 还有一点需要注意的就是为什么我们可以直接执行 nAdd()
,这是因为在 nAdd()
的前面没有使用 var
,因此 nAdd()
是一个全局函数而不是局部函数
所以,闭包的变量会常驻内存,滥用闭包容易造成内存泄漏,特别是在 IE 浏览器下,2020年了,应该没人使用 IE 了吧(小声bb),解决办法就是在退出函数之前,将不使用的局部变量全部删除,这也是上面讲了垃圾回收机制 => 内存泄漏,再讲到闭包的原因,我会尽量将有关联性的知识点一起讲了,也方便大家学习和加深印象。
相关免费学习推荐:javascript(视频)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!