一个JS内存泄露实例分析

在看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

时间: 2025-01-02 17:12:43

一个JS内存泄露实例分析的相关文章

句柄泄露实例分析

句柄泄露实例分析 在上篇文章.NET对象与Windows句柄(二):句柄分类和.NET句柄泄露的例子中,我们有一个句柄泄露的例子.例子中多次创建和Dispose了DataReceiver和DataAnalyzer对象,但由于忘记调用DataAnalyzer的Stop方法,导致产生句柄泄露.本文假定我们已经发现了泄露现象但还不知道原因,讨论如何在这种情况下分析问题. 一.发现问题 在程序运行约一个小时以后,通过任务管理器发现句柄数超过5000,线程数也超过1000.对于一段只需要并行接收和分析数据

js内存泄露学习(转)

http://blog.csdn.net/kaitiren/article/details/19974269内存泄露不错的帖子,感谢分享 Google Chrome浏览器提供了非常强大的JS调试工具,Heap Profiling便是其中一个.Heap Profiling可以记录当前的堆内存(heap)快照,并生成对象的描述文件,该描述文件给出了当时JS运行所用到的所有对象,以及这些对 ... 一.概述 Google Chrome浏览器提供了非常强大的JS调试工具,Heap Profiling便是

c/c++服务器程序内存泄露问题分析及解决

由 www.169it.com 搜集整理 对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题.已经有许多技术被研究出来以应对这个问题,比如 Smart Pointer,Garbage Collection等.Smart Pointer技术比较成熟,STL中已经包含支持Smart Pointer的class,但是它的使用似乎并不广泛,而且它也不能解决所有的问题:Garbage Collection技术在Java中已经比较成熟,但是在c/c++领域的发展并不顺畅,虽然很早就有人思考

.NET对象与Windows句柄(三):句柄泄露实例分析

在上篇文章.NET对象与Windows句柄(二):句柄分类和.NET句柄泄露的例子中,我们有一个句柄泄露的例子.例子中多次创建和Dispose了DataReceiver和DataAnalyzer对象,但由于忘记调用DataAnalyzer的Stop方法,导致产生句柄泄露.本文假定我们已经发现了泄露现象但还不知道原因,讨论如何在这种情况下分析问题. 一.发现问题 在程序运行约一个小时以后,通过任务管理器发现句柄数超过5000,线程数也超过1000.对于一段只需要并行接收和分析数据的简易代码来说,这

Android内存泄露案例分析

一款优秀的Android应用,不仅要有完善的功能,也要有良好的体验,而性能是影响体验的一个重要因素.内存泄露是Android开发中常见的性能问题.这篇文章,通过我们曾经遇到的一个真实的案例,来讲述一个内存泄露问题,从发现到分析定位,再到最终解决的全过程. 这里把整个过程分为四个阶段: 第一阶段,现场勘查,分析Bug现象,找出有用线索: 第二阶段,初步推断,根据之前的线索,推断可能导致Bug的原因,并且进一步验证推断是否正确: 第三阶段,探究根源,找出导致Bug的真正原因: 第四阶段,解决方案,研

node.js内存泄露问题记录

先说一下.事情的来龙去脉. 公司开发一款游戏棋牌游戏,服务端的开发是IO密集型,开发的时候,考虑过使用python,java,node.js. 终于选择了node.js(node.js宣传的杀手功能.异步IO,node.js另外一个分支叫io.js),事情也就由此而起. 由于第一次做手机游戏.对移动网络的预计不足.选择了json作为通信数据传输格式.上线后玩家就频繁掉线(通信数据量太大,移动网络hold不住), 于是想了一个解决方式,把json数据用zip压缩一下,事情好像就万事大吉了(尽管也有

查看w3wp进程占用的内存及.NET内存泄露,死锁分析--转载

一 基础知识 在分析之前,先上一张图: 从上面可以看到,这个w3wp进程占用了376M内存,启动了54个线程. 在使用windbg查看之前,看到的进程含有 *32 字样,意思是在64位机器上已32位方式运行w3wp进程.这个可以通过查看IIS Application Pool 的高级选项进行设置: 好了,接下打开Windbg看看这个w3wp进程占用了376M内存,启动的54个线程. 1. 加载 WinDbg SOS 扩展命令 .load C:\Windows\Microsoft.NET\Fram

Java 程序的内存泄露问题分析

什么是内存泄露? 广义的Memory Leak:应用占用了内存,但是不再使用(包括不能使用)该部分内存 狭义的Memory Leak:应用分配了内存,但是不能再获取该部分内存的引用(对于Java,也不能被GC) 一个具体的例子: 应用创建了一个长时间运行的Thread 该Thread使用ClassLoader(可以是定制的也可以是默认的)加载了一个类 这个类有一个Static域,指向了一大块内存,然后该Thread的ThreadLocal变量保存了这个类的引用. 最后该Thread清理了对所有已

Layer的内存泄露问题分析报告

[问题描述] home应用在运行monkey测试6个小时候,Native Heap增长到200MB,怀疑内存泄露. 我们可以动过dumpsys查看Native Heap的大小: $adb shell dumpsys meminfo com.miui.home Applications Memory Usage (kB): Uptime: 12929068 Realtime: 12929060 ** MEMINFO in pid 1393 [com.miui.home] ** Pss Privat