什么是内存泄漏?哪些情况造成内存泄露?

发布时间 2023-03-31 12:10:17作者: 小石糖记
内存泄漏是指:一块被分配的内存既不能使用又不能回收,直到浏览器进程结束;
以下列举内存泄漏的情况: 
<body>
    <div class="main">
      <div class="test">天</div>
      <div class="item">天</div>
      <div class="item">向</div>
      <button id="add">点击我增加</button>
      <button id="remove">点击我减少</button>
      <script>
       /*   1.意外的全局变量
      js对未声明变量会在全局最高对象上创建它的引用,(是以属性存在的,而不是变量),
      如果在浏览器上就是window对象,如果在node环境下就是global;
      如果未声明的变量缓存大量的数据,它可能只有在页面被刷新或者被关闭的时候才会释放内存,这样就造成了内存意外泄漏
     
      解决方案: 针对上面类型的内存泄漏我们在平时一定要声明变量,不要有全局直接引用。
      (在JavaScript文件中添加 “use strict”,开启严格模式,可以有效地避免上述问题。) */
      function my() {
        name = "my name is tom";
        my();
      }
      console.log(window);
运行结果:
      /*   2.console.log
      作为前端平时使用console.log在控制台打出相对应的信息可以说是非常常见。
      但如果没有去掉console.log可能会存在内存泄漏。
      因为在代码运行之后需要在开发工具能查看对象信息,所以传递给console.log的对象是不能被垃圾回收 */
     /*     3、闭包
      首先闭包是一个函数A返回一个内联的函数B,即使A函数执行完函数B也可以访问函数A里面的变量,这就是一个简单的闭包。
      本质上闭包是将函数内部和外部连接起来的一座桥梁。
     
      在my2()内部创建的sendName()函数是不会被回收的,因为它被全局变量test引用,处于随时被调用的状态。
      如果向释放内存可以设置test=null;由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。
      过度使用闭包可能会导致内存占用过多 */
      function my2(name){
        function sendName() {
         console.log(name)
        }
        return sendName
      }
        var test= my2("mary")
        test()
      /* 4、DOM泄漏
        浏览器中DOM和js采用的是不一样的引擎, DOM采用的是渲染引擎,而js采用的是v8引擎,所以在用js操作DOM时会比较耗费性能,因为他们需要桥来连接他们。
        为了减少DOM的操作,我们一般将常用的DOM,我们会采用变量引用的方式会将其缓存在当前环境。
        如果在进行一些删除、更新操作之后,可能会忘记释放已经缓存的DOM,话不多说直接来个例子
       
        在我点击了三次增加之后,可以明显的看到节点(绿线)有三次明显的增加,之后我又删除了一个节点,但绿线没有下降,这是为什么呢?,这也就是内存泄漏。
        原因就是删除的DOM在js中有全局的引用。也就是我删除的test在文中被引用,所以无法释放内存。所以在删除更新等操作后应该将其设置为null
    */
    var add =document.querySelector("#add");
    var remove=document.querySelector("#remove");
    var main=document.querySelector(".main")
    var test=document.querySelector(".test")
    add.onclick=function () {
      var itemN =document.createElement('div')
      var txt =document.createTextNode('上')
      itemN.appendChild(txt);
      main.appendChild(itemN);
    }
      remove.onclick=function (){
        main. removeChild(test)
      }
运行结果:

     

     /*  5、被遗忘的timers(定时器)

      js中常用的定时器setInterval(),setTimeout().他们都是规定延迟一定的时间执行某个代码,
      而其中setInterval()和链式setTimeout()在使用完之后如果没有手动关闭,会一直存在执行占用内存,
      所以在不用的时候我们可以通过clearInterval()、clearTimeout()来关闭其对应的定时器,释放内存。 */
   </script>
     
     
  </body>