【问题标题】:Chrome Profiler Javascript memory leakChrome Profiler Javascript 内存泄漏
【发布时间】:2015-07-28 10:23:47
【问题描述】:

为了在 Chrome 中使用分析器,我尝试编写内存泄漏的 javascript 代码。但是,探查器似乎没有显示它应该是什么。

这是我的代码:

<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 时,在我单击销毁后它没有显示对我的 Leaker 实例的任何引用(但它应该显示这样的引用,因为我在上面提到过,来自 setInterval 的闭包仍然保留着它)。

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

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

在控制台中,setInterval 仍在运行,尽管分析器向我们显示没有更多的 Leaker 实例。

我在垃圾收集的工作方式或 Chrome 分析器中遗漏了什么吗?

【问题讨论】:

    标签: javascript google-chrome memory-leaks profiler


    【解决方案1】:

    这两个分析器之间的区别在于,在您“销毁”leak 之前,Leaker 变量是全局变量,之后不是。因此,只有探查器(和 javascript 引擎)无法按照您描述的方式工作。基本上,您可以看到全局变量,但看不到局部范围的变量。我想根据范围进行不同的分配是有意义的。在您将泄漏设置为 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 分析器如何工作的最小示例。当变量是全局变量时,您会看到它并可以在类过滤器中对其进行过滤,但如果不是,则不能。

    现在,它显然还在某个地方。您可以检查关闭下拉菜单,您会看到两个快照上都有一个泄漏者:

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

    【讨论】:

      猜你喜欢
      • 2014-06-24
      • 2011-07-08
      • 2013-11-06
      • 2011-02-28
      • 1970-01-01
      • 2012-02-27
      • 2020-08-30
      • 1970-01-01
      相关资源
      最近更新 更多