资讯专栏INFORMATION COLUMN

内存泄漏

jeffrey_up / 3033人阅读

摘要:假如没有此时会进行优化把不会被任何闭包用到的变量从词法环境中去掉从而消除内存泄漏。良好的编码方式了解一下常见现象可以减少内存泄漏现象产生同时在由于失误产生泄漏时保持清醒的思路借助进行分析定位。

引言

内存泄漏一般是由于我们编码缺陷导致的,首先明确一下内存泄漏的定义,就是应用程序不需要,但是又不能返回给操作系统以供重新分配使用,导致可用内存越来越少的现象。下面总结一下在browser端内存泄漏几种方式

全局变量
function test () {
    age ="xxx"
    this.name = "ycg"
}
test()

说明
本来函数执行完栈释放,但是失误行为,导致栈中本应该声明为局部的变量变成了全局,导致变量所占用空间无法释放,好的编码习惯可以防止此类失误,例如借助eslint等

定时器
 var someResource = "jsdt".repeat(100000);
    setInterval(function() {
        var node = document.getElementById("node");
        if(node) {
            // Do stuff with node and someResource.
            node.innerHTML = JSON.stringify(someResource);
        }
    }, 100);

说明 由于定时器中持有node节点引用,导致即使node节点被移除,所占据空间任然无法被释放

闭包
var theThing = null;
var replaceThing = function () {
  var originalThing = theThing;
  // Define a closure that references originalThing but doesn"t ever
  // actually get called. But because this closure exists,
  // originalThing will be in the lexical environment for all
  // closures defined in replaceThing, instead of being optimized
  // out of it. If you remove this function, there is no leak.
  var unused = function () {
    if (originalThing)
      console.log("hi");
  };
  theThing = {
    longStr: new Date()+new Array(1000000).join("*"),
    // While originalThing is theoretically accessible by this
    // function, it obviously doesn"t use it. But because
    // originalThing is part of the lexical environment, someMethod
    // will hold a reference to originalThing, and so even though we
    // are replacing theThing with something that has no effective
    // way to reference the old value of theThing, the old value
    // will never get cleaned up!
    someMethod: function () {}
  };
  // If you add `originalThing = null` here, there is no leak.
};
setInterval(replaceThing, 1000);

说明 注释中已经很好的说明了产生现象的原因,就是说同一父级作用域创建的各种闭包作用域是共享的,unused引用originalThing,虽没使用,但是词法作用域环境已经创建。假如没有unused,此时v8会进行优化,把不会被任何闭包用到的变量从词法环境中去掉,从而消除内存泄漏。下图是我本地browser实验现象截取,可以看到使用内存一直在增加,并且从对比视图中看到,一直有新的string被创建,只增不减。

游离DOM引用

图示dom树中,如果#tree变成游离态,但是叶子节点leaf被js变量引用。除非消除引用,否则游离态的#tree无法被GC

总结

首先必须明确的概念是浏览器不能帮助我们解决内存泄漏,只是帮我们GC,免得人力手动GC。GC算法规则限制了只能清除符合特定条件的对象。良好的编码方式,了解一下常见memory leak现象可以减少内存泄漏现象产生,同时在由于失误产生泄漏时,保持清醒的思路,借助devtool进行分析定位。

参考链接

https://blog.meteor.com/an-in...
https://blog.sessionstack.com...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88992.html

相关文章

  • VueJS SSR 后端绘制内存泄漏的相关解决经验

    摘要:积少成多,最后造成内存泄漏。前端内存泄漏的影响,都是发生在客户机器上,而且基本上现代浏览器也会做好保护机制,一般自行刷新之后都会解决。但是,一旦后端绘制内存泄漏造成宕机之后,整个服务器都会受影响,危险性更大,搞不好年终奖就没了。 引言 Memory Leak 是最难排查调试的 Bug 种类之一,因为内存泄漏是个 undecidable problem,只有开发者才能明确一块内存是不是需...

    lifesimple 评论0 收藏0
  • 内存泄漏优化

    摘要:内存泄漏会造成什么影响它是造成应用程序的主要原因之一。静态变量引用不当会导致内存泄漏静态变量和会导致内存泄漏,在下面这段代码中对的和设置为静态对象,从而产生内存泄漏。 目录介绍: 1.什么是内存泄漏 2.内存泄漏造成什么影响 3.内存泄漏检测的工具有哪些 4.关于Leakcanary使用介绍 5.Leakcanary捕捉常见的内存泄漏及解决办法 5.0.1 错误使用单例造成的内存...

    icyfire 评论0 收藏0

发表评论

0条评论

jeffrey_up

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<