• 一个JS内存泄露实例分析


    本文地址 http://www.cnblogs.com/jasonxuli/p/6264174.html
     
    在看JS GC 相关的文章时,好几次看到了下面这个设计出来的例子,比较巧妙,环环相扣。
     
    var theThing = null;
    var replaceThing = function () {
        var originalThing = theThing;
        var unused = function () {
            if (originalThing)
                console.log("hi");
        };
        theThing = {
            longStr: new Array(10000).join('*'),
            someMethod: function () {
                console.log(1111);
            }
        };
    };
     
    setInterval(replaceThing, 1000);
    由于 V8 GC 的关键是 root 级对象,因此内存泄露基本上都是由于 root 级引用没有被释放导致的。
     
    上面代码中的 root 主要有两个,一个是 theThing,另一个是 replaceThing 运行时的调用栈。这里的内存泄露主要是 theThing。
     
    总体来说是因为,root 级对象 theThing 持有了 replaceThing1 内部对象的引用,并且在下一次把引用转交给了 replaceThing2,然后持有了 replaceThing2 的内部引用。
    详细一点:theThing 持有了 longStr 和 someMethod 的引用,由于 someMethod 这个闭包会保留它的 context,因此 replaceThing 整体被保留了,于是 unused 被保留;而 unused 又持有了 originalThing 的引用,因此 originalThing 持有了 由 theThing 转交过来的前一个 setInterval 时的 someMethod 和 longStr。 一次又一次 setInterval 下去,longStr 和 someMethod 就被串了起来。
     
    图解:
     
    setInterval1:
     
      originalThing           theThing
               |                           |
             null             someMethod1
     
     
    setInterval2:
     
      originalThing           theThing
              |                            |
    someMethod1    someMethod2   --unused--> replaceThing1 --> someMethod1
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    ecshop 在首页每个商品下显示已销售数量
    ecshop 用户名和邮箱都能登陆
    ecshop 模版商品详情页,不同商品调用不同模板
    ecshop文章详情页显示浏览数
    让ecshop编辑器功能更强大
    ecshop 改变sitemap.xml的位置
    ecshop 广告位固定
    ecshop 点购物车弹出提示框
    (三)简单工厂模式详解
    (一)单例模式详解
  • 原文地址:https://www.cnblogs.com/jasonxuli/p/6264174.html
Copyright © 2020-2023  润新知