Chrome 分析器 JavaScript 内存泄漏

13

我试图编写一个含有内存泄漏的 JavaScript 代码,以便与 Chrome 中的分析器一起使用。然而,似乎分析器没有展示应该展示的内容。

这是我的代码:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button id="start_button">Start</button>
<button id="destroy_button">Destroy</button>

<script type="text/javascript" charset="utf-8">
var Leaker = function(){};

Leaker.prototype = {
                init:function(){
                        this._interval = null;
                        this.start();
                },
                start: function(){
                        var self = this;
                        this._interval = setInterval(function(){ self.onInterval(); }, 100);
                },
                onInterval: function(){ console.log("Interval"); }
};

$("#start_button").click(function(){
        if(leak !== null && leak !== undefined){
            return;
        }

        leak = new Leaker();
        leak.init();

});

$("#destroy_button").click(function(){
        leak = null;
});

var leak;

</script>

当我点击开始按钮时,会创建一个新的对象Leaker。而当我点击销毁按钮时,该对象将被设置为null(注意:但它不会被垃圾收集,因为setInterval仍在工作)。

问题:然而,当我使用Google Chrome分析器时,它并没有显示任何对我的Leaker实例的引用,即使在我点击销毁后(但它应该显示这样的引用,因为如上所述,setInterval的闭包仍然保留着它)。

在点击销毁按钮之前的分析器: 点击销毁按钮之前的分析器

在点击销毁按钮后的分析器(您可以看到我再也找不到leaker实例了,而它应该还在那里)。

点击销毁按钮后的分析器

这里是控制台,尽管分析器显示我们没有Leaker实例了,但setInterval仍然在运行。

控制台和setInterval

我是否在垃圾回收的工作方式或Chrome分析器方面遗漏了什么?

1个回答

2
两个性能分析工具的区别在于,在你“销毁”leak之前,Leaker变量是全局的,销毁后则不是。因此,只有性能分析工具(以及JavaScript引擎)不按照您描述的方式工作。基本上,您可以看到全局变量,但无法看到本地作用域变量。我想根据作用域进行不同的分配是有道理的。在将leak设置为null之前,它需要对其他脚本可用。
您可以通过一个最小示例看到性能分析工具如何根据作用域而异。

var Leaker = function() {};

var Leaker2 = function() {};

// this one is going to be in the profiler
var leak = new Leaker();

(function(){
    // this one is not in the profiler
    var leak2 = new Leaker2();
    setInterval(function(){console.log(leak2)}, 500);
})()

编辑:

为了澄清,该对象仍然在分析器中,并且已经被分配,但不像全局变量那样。我只是创建一个最小的示例来展示Chrome分析器的工作原理。当一个变量是全局的时候,你会看到它并可以在类过滤器中过滤它,但如果不是,就不能。

现在,很明显它仍然存在某个地方。你可以检查闭包下拉菜单,你会发现你有一个Leaker在两个快照中:

enter image description here

也许在闭包中创建了一个副本,以便可以分配上下文信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接