简体   繁体   English

Chrome Profiler Javascript内存泄漏

[英]Chrome Profiler Javascript memory leak

I tried to write a javascript code with a memory leak in order to work with the profiler in Chrome. 我尝试编写带有内存泄漏的javascript代码,以便与Chrome中的探查器一起使用。 However, it seems the profiler isn't showing what it should be. 然而,似乎剖析器没有显示它应该是什么。

Here's my code : 这是我的代码:

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

You can see when I click on start button a new object Leaker is created. 你可以看到我点击开始按钮时创建了一个新的对象Leaker。 And when I click on destroy, the object is set to null (NOTE: But it won't be garbage collected since the setInterval will be still working). 当我点击destroy时,该对象被设置为null(注意:但它不会被垃圾收集,因为setInterval仍然可以工作)。

Problem : However, when I use the Google Chrome Profiler it doesn't show me any reference to my Leaker instance after I click on destroy (but it should show me such a reference, since as I noted above, the closure from setInterval is still holding onto it). 问题 :然而,当我使用Google Chrome Profiler时,我点击destroy后没有向我显示对Leaker实例的任何引用(但它应该向我显示这样的引用,因为如上所述,setInterval的闭包仍然是抓住它)。

Profiler before clicking on destroy button 在点击销毁按钮之前的Profiler 在点击销毁按钮之前的Profiler

Profiler after clicking on destroy button (you can see I can't find leaker instance anymore, whereas it should be there). 点击破坏按钮后的Profiler(你可以看到我再也找不到leaker实例,而它应该在那里)。

点击破坏按钮后的Profiler

And here the console, the setInterval is still in action eventhough the profiler show us there is no more Leaker instances. 在这里控制台,setInterval仍然在运行,尽管探查器告诉我们没有更多的Leaker实例。

Console&setInterval

Am I missing something on the way garbage collecting works or the Chrome profiler ? 我是否在垃圾收集工作方式或Chrome分析器上遗漏了什么?

The difference between the two profilers is that before you "destroy" leak , the Leaker variable is global and after it's not. 两个分析器之间的区别在于,在“破坏” leak ,Leaker变量是全局的,而不是之后。 So it's just the profiler (and the javascript engine) that doesn't work the way you describe it. 所以它只是探测器(和javascript引擎)不能像你描述的那样工作。 Basically, you can see global variables, but not locally scoped variables. 基本上,您可以看到全局变量,但不能看到本地范围的变量。 I guess it makes sense to allocate differently based on the scope. 我想根据范围进行不同的分配是有意义的。 Until you set leak to null, it needs to be available to other scripts. 在将leak设置为null之前,它需要可供其他脚本使用。

You can see with a minimal example how the profiler works differently based on the scope: 您可以使用最小示例查看概要分析器如何根据范围进行不同的工作:

 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); })() 

EDIT: 编辑:

Just to clarify, the object is still in the profiler, and still allocated, but not the same way a global is. 只是为了澄清,该对象仍在分析器中,并且仍然分配,但与全局不同。 I was just creating a minimal example of how Chrome profiler works. 我只是创建了一个关于Chrome Profiler如何工作的最小示例。 When a variable is global, you'll see it in and can filter it in the class filter, but if not you can't. 当变量是全局变量时,您将看到它并且可以在类过滤器中对其进行过滤,但如果不是,则不能。

Now, it is still somewhere, obviously. 现在,它显然仍然在某个地方。 You can check in closures drop down, you'll see you have a Leaker there on both snapshots : 您可以检查关闭下拉菜单,您会看到两个快照上都有Leaker:

在此输入图像描述

Maybe a duplicate is created when in a closure, so that context info can be allocated as well. 在闭包中可能会创建副本,因此也可以分配上下文信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM