• 技术文章 >web前端 >前端问答

    javascript内存泄漏的原因有哪些

    青灯夜游青灯夜游2021-11-19 16:37:51原创497

    javascript内存泄漏的原因:1、全局变量使用不当;2、闭包使用不当;3、延时器或定时器没有被清除;4、没有清理的DOM元素引用(dom清空或删除时,事件未清除)。

    本教程操作环境:windows7系统、javascript1.8.5版、Dell G3电脑。

    内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。即指由于疏忽或错误造成程序未能释放已经不再使用的内存。 内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。这里就讲一些常见会带来内存泄露的原因。

    1. 全局变量

    JavaScript可以处理没有声明的变量:一个未声明的变量的引用在全局对象中创建了一个新变量。在浏览器的环境中,全局对象是window。

    function foo(){
      name = '前端曰';
    }
    // 其实是把name变量挂载在window对象上
    function foo(){
      window.name = '前端曰';
    }
    
    // 又或者
    function foo(){
      this.name = '前端曰';
    }
    foo() // 其实这里的this就是指向的window对象

    这样无意中一个意外的全局变量就被创建了,为了阻止这种错误发生,在你的Javascript文件最前面添加 ‘use strict;’ 。这开启了解析JavaScript的阻止意外全局的更严格的模式。或者自己注意好变量的定义!

    2. 闭包

    闭包:匿名函数可以访问父级作用域的变量。

    var names = (function(){  
        var name = 'js-say';
        return function(){
            console.log(name);
        }
    })()

    闭包会造成对象引用的生命周期脱离当前函数的上下文,如果闭包使用不当,可以导致环形引用(circular reference),类似于死锁,只能避免,无法发生之后解决,即使有垃圾回收也还是会内存泄露。

    3. 被遗忘的延时器/定时器

    在我们的日常需求中,可能会经常试用到 setInterval/setTimeout ,但是使用完之后通常忘记清理。

    var someResource = getData(); 
    setInterval(function() { 
        var node = document.getElementById('Node'); 
        if(node) { 
            // 处理 node 和 someResource 
            node.innerHTML = JSON.stringify(someResource)); 
        } 
    }, 1000);

    setInterval/setTimeout 中的 this 指向的是window对象,所以内部定义的变量也挂载到了全局;if 内引用了 someResource 变量,如果没有清除 setInterval/setTimeout 的话someResource 也得不到释放;同理其实 setTimeout 也一样。所以我们用完需要记得去 clearInterval/clearTimeout。

    4、没有清理的DOM元素引用(dom清空或删除时,事件未清除

    var elements = {
        button: document.getElementById('button'),
        image: document.getElementById('image'),
        text: document.getElementById('text')
    };
    function doStuff() {
        image.src = 'http://some.url/image';
        button.click();
        console.log(text.innerHTML);
    }
    function removeButton() {
        document.body.removeChild(document.getElementById('button'));
        // 此时,仍旧存在一个全局的 #button 的引用
        // elements 字典。button 元素仍旧在内存中,不能被 GC 回收。
    }

    【推荐学习:javascript高级教程

    以上就是javascript内存泄漏的原因有哪些的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:javascript 内存泄漏
    上一篇:html中li是什么 下一篇:JavaScript中数据类型转换函数有哪些
    千万级数据并发解决方案

    相关文章推荐

    • javascript怎么实现魔方效果• javascript变量命名区分大小写吗• 怎么用javascript实现n的阶乘• javascript文件是病毒吗
    1/1

    PHP中文网