Chrome 探查器 Javascript 内存泄漏

Chrome Profiler Javascript memory leak

我试图编写一个 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。 当我点击 destroy 时,该对象被设置为 null(注意:但它不会被垃圾回收,因为 setInterval 仍然有效)。

问题:但是,当我使用 Google Chrome Profiler 时,在我单击destroy(但它应该向我显示这样的参考,因为正如我上面提到的,来自 setInterval 的闭包仍然保留着它)。

点击销毁按钮前的探查器

点击销毁按钮后的探查器(你可以看到我再也找不到泄密者实例了,而它应该在那里)。

这里是控制台,setInterval 仍在运行,尽管探查器显示我们没有更多的 Leaker 实例。

我是否遗漏了垃圾收集工作的方式或 Chrome 分析器?

这两个分析器的区别在于,在您 "destroy" 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 分析器如何工作的最小示例。当变量是全局变量时,您会在 class 过滤器中看到它并可以对其进行过滤,但如果不是,则不能。

现在,它显然还在某个地方。你可以检查关闭下拉列表,你会看到你在两个快照上都有一个 Leaker :

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