Table des matières
Variable globale inattendue" >Variable globale inattendue
Solution : " >Solution :
console.log" >console.log
Exemple------>demos/log.html" >Exemple------>demos/log.html
closures(闭包)" >closures(闭包)
实例------>demos/closures.html" >实例------>demos/closures.html
DOM泄露" >DOM泄露
实例------>demos/dom.html" >实例------>demos/dom.html
小试牛刀------>demos/dom_practice.html" >小试牛刀------>demos/dom_practice.html
timers" >timers
Maison interface Web js tutoriel Fuites de mémoire JavaScript courantes

Fuites de mémoire JavaScript courantes

Dec 05, 2017 pm 04:31 PM
javascript js Laisser Passer

Qu'est-ce qu'une fuite de mémoire

Une fuite de mémoire fait référence à un programme qui ne parvient pas à être publié en raison d'une négligence ou une erreur et n'est plus utilisé de mémoire. Les fuites de mémoire ne font pas référence à la disparition physique de la mémoire, mais plutôt au fait qu'après que l'application ait alloué un certain segment de mémoire, en raison d'une erreur de conception, elle perd le contrôle du segment de mémoire avant qu'il ne soit libéré, provoquant ainsi un problème. gaspillage de mémoire.
Les fuites de mémoire ne peuvent généralement être analysées que par les programmeurs ayant accès au code source du programme. Cependant, de nombreuses personnes ont l'habitude de décrire toute augmentation indésirable de l'utilisation de la mémoire comme une fuite de mémoire, même si cela n'est pas strictement exact.
————wikipedia

Variable globale inattendue

Comment JavaScript gère les variables non déclarées : dans le global Créer une référence à la variable sur l'objet (c'est-à-dire une propriété sur l'objet global, pas une variable, car elle peut être supprimée via delete). Si vous êtes dans un navigateur, l'objet global est l'objet fenêtre.

Si les variables non déclarées mettent en cache une grande quantité de données, les données ne peuvent être libérées que lorsque la fenêtre est fermée ou que la page est actualisée. Cela peut provoquer des fuites de mémoire inattendues.

<span style="font-size: 14px;">function foo(arg) {<br>    bar = "this is a hidden global variable with a large of data";<br>}<br></span>
Copier après la connexion

équivaut à :

<span style="font-size: 14px;">function foo(arg) {<br>    window.bar = "this is an explicit global variable with a large of data";<br>}<br></span>
Copier après la connexion

De plus, des variables globales inattendues sont créées via ceci :

<span style="font-size: 14px;">function foo() {<br>    this.variable = "potential accidental global";<br>}<br><br>// 当在全局作用域中调用foo函数,此时this指向的是全局对象(window),而不是'undefined'<br>foo();<br></span>
Copier après la connexion

Solution :

Ajoutez « use strict » dans le fichier JavaScript et activez le mode strict, ce qui peut efficacement éviter les problèmes ci-dessus.

<span style="font-size: 14px;">function foo(arg) {<br>    "use strict" // 在foo函数作用域内开启严格模式<br>    bar = "this is an explicit global variable with a large of data";// 报错:因为bar还没有被声明<br>}<br></span>
Copier après la connexion

Si vous devez utiliser des variables globales dans une fonction, vous pouvez les déclarer explicitement dans la fenêtre comme indiqué dans le code suivant :

<span style="font-size: 14px;">function foo(arg) {<br>    window.bar = "this is a explicit global variable with a large of data";<br>}<br></span>
Copier après la connexion

Ceci est non seulement très lisible, mais également pratique pour une maintenance ultérieure

En ce qui concerne les variables globales, vous devez faire attention à ces variables globales utilisé pour stocker temporairement de grandes quantités de données et assurez-vous de le définir sur null ou de le réaffecter après le traitement de ces données. Les variables globales sont également couramment utilisées comme cache. Généralement, le cache est utilisé pour l'optimisation des performances, il est préférable de définir une limite supérieure sur la taille du cache. Étant donné que le cache ne peut pas être récupéré, un cache plus élevé entraînera une consommation de mémoire plus élevée.

console.log

console.log : imprime un message sur la console de développement Web, souvent utilisé pour le débogage et l'analyse lors développement . Parfois, pendant le développement, vous devez imprimer certaines informations sur les objets, mais oubliez de supprimer l'instruction console.log lors de la publication, ce qui peut provoquer des fuites de mémoire.

L'objet transmis à console.log ne peut pas être récupéré ♻️ car l'outil de développement doit pouvoir afficher les informations sur l'objet après l'exécution du code. Il est donc préférable de ne pas consoler.enregistrer aucun objet dans l'environnement de production.

Exemple------>demos/log.html

<span style="font-size: 14px;"><!DOCTYPE html><br><html lang="en"><br><br><head><br>  <meta charset="UTF-8"><br>  <meta name="viewport" content="width=device-width, initial-scale=1.0"><br>  <meta http-equiv="X-UA-Compatible" content="ie=edge"><br>  <title>Leaker</title><br></head><br><br><body><br>  <input type="button" value="click"><br>  <script><br>    !function () {<br>      function Leaker() {<br>        this.init();<br>      };<br>      Leaker.prototype = {<br>        init: function () {<br>          this.name = (Array(100000)).join('*');<br>          console.log("Leaking an object %o: %o", (new Date()), this);// this对象不能被回收<br>        },<br><br>        destroy: function () {<br>          // do something....<br>        }<br>      };<br>      document.querySelector('input').addEventListener('click', function () {<br>        new Leaker();<br>      }, false);<br>    }()<br>  </script><br></body><br><br></html><br></span>
Copier après la connexion

Ici combiné avec les outils de développement de Chrome–>Performances Effectuez une analyse. Les étapes sont les suivantes :

⚠️Remarque : Il est préférable d'effectuer l'analyse dans une fenêtre masquée pour éviter que les plug-ins du navigateur n'affectent les résultats de l'analyse

  1. Ouvrez l'enregistrement de l'élément [Performance]

  2. Exécutez CG une fois et créez une ligne de référence de base

  3. Cliquez trois fois de suite sur le bouton [cliquez] pour créer trois nouveaux objets Leaker

  4. Exécuter CG une fois

  5. Arrêter l'enregistrement

Fuites de mémoire JavaScript courantes

On voit que la ligne [JS Heap] est à la fin. Sans revenir à la ligne de référence de base, il y a évidemment de la mémoire qui n'a pas été récupérée. Si vous modifiez le code pour :

<span style="font-size: 14px;">    !function () {<br>      function Leaker() {<br>        this.init();<br>      };<br>      Leaker.prototype = {<br>        init: function () {<br>          this.name = (Array(100000)).join('*');<br>        },<br><br>        destroy: function () {<br>          // do something....<br>        }<br>      };<br>      document.querySelector('input').addEventListener('click', function () {<br>        new Leaker();<br>      }, false);<br>    }()<br></span>
Copier après la connexion

supprimez la console.log("Leaking an object %o: %o", (new Date()), this instruction); . Répétez les étapes ci-dessus, et les résultats de l'analyse sont les suivants :

Fuites de mémoire JavaScript courantes

D'après les résultats de l'analyse comparative, on peut voir que les objets imprimés par la console .log ne sera pas récupéré. Par conséquent, il est préférable de ne pas consoler.enregistrer des objets volumineux dans la page, car cela pourrait affecter les performances globales de la page, en particulier dans un environnement de production. En plus de console.log, il existe également des problèmes similaires tels que console.dir, console.error, console.warn, etc. Ces détails nécessitent une attention particulière.

closures(闭包)

当一个函数A返回一个内联函数B,即使函数A执行完,函数B也能访问函数A作用域内的变量,这就是一个闭包——————本质上闭包是将函数内部和外部连接起来的一座桥梁。

<span style="font-size: 14px;">function foo(message) {<br>    function closure() {<br>        console.log(message)<br>    };<br>    return closure;<br>}<br><br>// 使用<br>var bar = foo("hello closure!");<br>bar()// 返回 'hello closure!'<br></span>
Copier après la connexion

在函数foo内创建的函数closure对象是不能被回收掉的,因为它被全局变量bar引用,处于一直可访问状态。通过执行bar()可以打印出hello closure!。如果想释放掉可以将bar = null即可。

由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过度使用闭包可能会导致内存占用过多。

实例------>demos/closures.html

<span style="font-size: 14px;"><!DOCTYPE html><br><html lang="en"><br><br><head><br>  <meta charset="UTF-8"><br>  <meta name="viewport" content="width=device-width, initial-scale=1.0"><br>  <meta http-equiv="X-UA-Compatible" content="ie=edge"><br>  <title>Closure</title><br></head><br><br><body><br>  <p>不断单击【click】按钮</p><br>  <button id="click_button">Click</button><br>  <script><br>    function f() {<br>      var str = Array(10000).join('#');<br>      var foo = {<br>        name: 'foo'<br>      }<br>      function unused() {<br>        var message = 'it is only a test message';<br>        str = 'unused: ' + str;<br>      }<br>      function getData() {<br>        return 'data';<br>      }<br>      return getData;<br>    }<br><br>    var list = [];<br>    <br>    document.querySelector('#click_button').addEventListener('click', function () {<br>      list.push(f());<br>    }, false);<br>  </script><br></body><br><br></html><br></span>
Copier après la connexion

这里结合Chrome的Devtools->Memory工具进行分析,操作步骤如下:

⚠️注:最好在隐藏窗口中进行分析工作,避免浏览器插件影响分析结果

  1. 选中【Record allocation timeline】选项

  2. 执行一次CG

  3. 单击【start】按钮开始记录堆分析

  4. 连续单击【click】按钮十多次

  5. 停止记录堆分析

Fuites de mémoire JavaScript courantes

上图中蓝色柱形条表示随着时间新分配的内存。选中其中某条蓝色柱形条,过滤出对应新分配的对象:

Fuites de mémoire JavaScript courantes

查看对象的详细信息:

Fuites de mémoire JavaScript courantes

从图可知,在返回的闭包作用链(Scopes)中携带有它所在函数的作用域,作用域中还包含一个str字段。而str字段并没有在返回getData()中使用过。为什么会存在在作用域中,按理应该被GC回收掉, why

原因是在相同作用域内创建的多个内部函数对象是共享同一个变量对象(variable object)。如果创建的内部函数没有被其他对象引用,不管内部函数是否引用外部函数的变量和函数,在外部函数执行完,对应变量对象便会被销毁。反之,如果内部函数中存在有对外部函数变量或函数的访问(可以不是被引用的内部函数),并且存在某个或多个内部函数被其他对象引用,那么就会形成闭包,外部函数的变量对象就会存在于闭包函数的作用域链中。这样确保了闭包函数有权访问外部函数的所有变量和函数。了解了问题产生的原因,便可以对症下药了。对代码做如下修改:

<span style="font-size: 14px;">    function f() {<br>      var str = Array(10000).join('#');<br>      var foo = {<br>        name: 'foo'<br>      }<br>      function unused() {<br>        var message = 'it is only a test message';<br>        // str = 'unused: ' + str; //删除该条语句<br>      }<br>      function getData() {<br>        return 'data';<br>      }<br>      return getData;<br>    }<br><br>    var list = [];<br>    <br>    document.querySelector('#click_button').addEventListener('click', function () {<br>      list.push(f());<br>    }, false);<br></span>
Copier après la connexion

getData()和unused()内部函数共享f函数对应的变量对象,因为unused()内部函数访问了f作用域内str变量,所以str字段存在于f变量对象中。加上getData()内部函数被返回,被其他对象引用,形成了闭包,因此对应的f变量对象存在于闭包函数的作用域链中。这里只要将函数unused中str = 'unused: ' + str;语句删除便可解决问题。

Fuites de mémoire JavaScript courantes

查看一下闭包信息:

Fuites de mémoire JavaScript courantes

DOM泄露

在JavaScript中,DOM操作是非常耗时的。因为JavaScript/ECMAScript引擎独立于渲染引擎,而DOM是位于渲染引擎,相互访问需要消耗一定的资源。如Chrome浏览器中DOM位于WebCore,而JavaScript/ECMAScript位于V8中。假如将JavaScript/ECMAScript、DOM分别想象成两座孤岛,两岛之间通过一座收费桥连接,过桥需要交纳一定“过桥费”。JavaScript/ECMAScript每次访问DOM时,都需要交纳“过桥费”。因此访问DOM次数越多,费用越高,页面性能就会受到很大影响。了解更多ℹ️

Fuites de mémoire JavaScript courantes

为了减少DOM访问次数,一般情况下,当需要多次访问同一个DOM方法或属性时,会将DOM引用缓存到一个局部变量中。但如果在执行某些删除、更新操作后,可能会忘记释放掉代码中对应的DOM引用,这样会造成DOM内存泄露。

实例------>demos/dom.html

<span style="font-size: 14px;"><!DOCTYPE html><br><html lang="en"><br><head><br>  <meta charset="UTF-8"><br>  <meta name="viewport" content="width=device-width, initial-scale=1.0"><br>  <meta http-equiv="X-UA-Compatible" content="ie=edge"><br>  <title>Dom-Leakage</title><br></head><br><body><br>  <input type="button" value="remove" class="remove"><br>  <input type="button" value="add" class="add"><br><br>  <p class="container"><br>    <pre class="wrapper">

  


  

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment mettre en œuvre un système de reconnaissance vocale en ligne à l'aide de WebSocket et JavaScript Comment mettre en œuvre un système de reconnaissance vocale en ligne à l'aide de WebSocket et JavaScript Dec 17, 2023 pm 02:54 PM

Comment utiliser WebSocket et JavaScript pour mettre en œuvre un système de reconnaissance vocale en ligne Introduction : Avec le développement continu de la technologie, la technologie de reconnaissance vocale est devenue une partie importante du domaine de l'intelligence artificielle. Le système de reconnaissance vocale en ligne basé sur WebSocket et JavaScript présente les caractéristiques d'une faible latence, d'un temps réel et d'une multiplateforme, et est devenu une solution largement utilisée. Cet article explique comment utiliser WebSocket et JavaScript pour implémenter un système de reconnaissance vocale en ligne.

Outils essentiels pour l'analyse boursière : découvrez les étapes pour dessiner des graphiques en bougies avec PHP et JS Outils essentiels pour l'analyse boursière : découvrez les étapes pour dessiner des graphiques en bougies avec PHP et JS Dec 17, 2023 pm 06:55 PM

Outils essentiels pour l'analyse boursière : découvrez les étapes pour dessiner des graphiques en bougies en PHP et JS. Des exemples de code spécifiques sont nécessaires. Avec le développement rapide d'Internet et de la technologie, le trading d'actions est devenu l'un des moyens importants pour de nombreux investisseurs. L'analyse boursière est une partie importante de la prise de décision des investisseurs, et les graphiques en bougies sont largement utilisés dans l'analyse technique. Apprendre à dessiner des graphiques en bougies à l'aide de PHP et JS fournira aux investisseurs des informations plus intuitives pour les aider à prendre de meilleures décisions. Un graphique en chandeliers est un graphique technique qui affiche les cours des actions sous forme de chandeliers. Il montre le cours de l'action

Recommandé : Excellent projet de détection et de reconnaissance des visages open source JS Recommandé : Excellent projet de détection et de reconnaissance des visages open source JS Apr 03, 2024 am 11:55 AM

La technologie de détection et de reconnaissance des visages est déjà une technologie relativement mature et largement utilisée. Actuellement, le langage d'application Internet le plus utilisé est JS. La mise en œuvre de la détection et de la reconnaissance faciale sur le front-end Web présente des avantages et des inconvénients par rapport à la reconnaissance faciale back-end. Les avantages incluent la réduction de l'interaction réseau et de la reconnaissance en temps réel, ce qui réduit considérablement le temps d'attente des utilisateurs et améliore l'expérience utilisateur. Les inconvénients sont les suivants : il est limité par la taille du modèle et la précision est également limitée ; Comment utiliser js pour implémenter la détection de visage sur le web ? Afin de mettre en œuvre la reconnaissance faciale sur le Web, vous devez être familier avec les langages et technologies de programmation associés, tels que JavaScript, HTML, CSS, WebRTC, etc. Dans le même temps, vous devez également maîtriser les technologies pertinentes de vision par ordinateur et d’intelligence artificielle. Il convient de noter qu'en raison de la conception du côté Web

WebSocket et JavaScript : technologies clés pour mettre en œuvre des systèmes de surveillance en temps réel WebSocket et JavaScript : technologies clés pour mettre en œuvre des systèmes de surveillance en temps réel Dec 17, 2023 pm 05:30 PM

WebSocket et JavaScript : technologies clés pour réaliser des systèmes de surveillance en temps réel Introduction : Avec le développement rapide de la technologie Internet, les systèmes de surveillance en temps réel ont été largement utilisés dans divers domaines. L'une des technologies clés pour réaliser une surveillance en temps réel est la combinaison de WebSocket et de JavaScript. Cet article présentera l'application de WebSocket et JavaScript dans les systèmes de surveillance en temps réel, donnera des exemples de code et expliquera leurs principes de mise en œuvre en détail. 1. Technologie WebSocket

Comment mettre en œuvre un système de réservation en ligne à l'aide de WebSocket et JavaScript Comment mettre en œuvre un système de réservation en ligne à l'aide de WebSocket et JavaScript Dec 17, 2023 am 09:39 AM

Comment utiliser WebSocket et JavaScript pour mettre en œuvre un système de réservation en ligne. À l'ère numérique d'aujourd'hui, de plus en plus d'entreprises et de services doivent fournir des fonctions de réservation en ligne. Il est crucial de mettre en place un système de réservation en ligne efficace et en temps réel. Cet article explique comment utiliser WebSocket et JavaScript pour implémenter un système de réservation en ligne et fournit des exemples de code spécifiques. 1. Qu'est-ce que WebSocket ? WebSocket est une méthode full-duplex sur une seule connexion TCP.

Comment utiliser JavaScript et WebSocket pour mettre en œuvre un système de commande en ligne en temps réel Comment utiliser JavaScript et WebSocket pour mettre en œuvre un système de commande en ligne en temps réel Dec 17, 2023 pm 12:09 PM

Introduction à l'utilisation de JavaScript et de WebSocket pour mettre en œuvre un système de commande en ligne en temps réel : avec la popularité d'Internet et les progrès de la technologie, de plus en plus de restaurants ont commencé à proposer des services de commande en ligne. Afin de mettre en œuvre un système de commande en ligne en temps réel, nous pouvons utiliser les technologies JavaScript et WebSocket. WebSocket est un protocole de communication full-duplex basé sur le protocole TCP, qui peut réaliser une communication bidirectionnelle en temps réel entre le client et le serveur. Dans le système de commande en ligne en temps réel, lorsque l'utilisateur sélectionne des plats et passe une commande

Conseils de développement PHP et JS : maîtrisez la méthode de création de graphiques en bougies boursières Conseils de développement PHP et JS : maîtrisez la méthode de création de graphiques en bougies boursières Dec 18, 2023 pm 03:39 PM

Avec le développement rapide de la finance sur Internet, l'investissement en actions est devenu le choix de plus en plus de personnes. Dans le trading d'actions, les graphiques en bougies sont une méthode d'analyse technique couramment utilisée. Ils peuvent montrer l'évolution des cours des actions et aider les investisseurs à prendre des décisions plus précises. Cet article présentera les compétences de développement de PHP et JS, amènera les lecteurs à comprendre comment dessiner des graphiques en bougies boursières et fournira des exemples de code spécifiques. 1. Comprendre les graphiques en bougies boursières Avant de présenter comment dessiner des graphiques en bougies boursières, nous devons d'abord comprendre ce qu'est un graphique en bougies. Les graphiques en chandeliers ont été développés par les Japonais

JavaScript et WebSocket : créer un système efficace de prévisions météorologiques en temps réel JavaScript et WebSocket : créer un système efficace de prévisions météorologiques en temps réel Dec 17, 2023 pm 05:13 PM

JavaScript et WebSocket : Construire un système efficace de prévisions météorologiques en temps réel Introduction : Aujourd'hui, la précision des prévisions météorologiques revêt une grande importance pour la vie quotidienne et la prise de décision. À mesure que la technologie évolue, nous pouvons fournir des prévisions météorologiques plus précises et plus fiables en obtenant des données météorologiques en temps réel. Dans cet article, nous apprendrons comment utiliser la technologie JavaScript et WebSocket pour créer un système efficace de prévisions météorologiques en temps réel. Cet article démontrera le processus de mise en œuvre à travers des exemples de code spécifiques. Nous

See all articles