Утечка памяти Javascript
Я попытался написать код 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 Profiler, он не показывает мне никаких ссылок на мой экземпляр Leaker после того, как я нажму на destroy (но он должен показать мне такую ссылку, поскольку as Я отметил выше, закрытие от setInterval все еще держится на нем).
Профилировщик перед нажатием кнопки уничтожения
![Профилировать до нажатия кнопки уничтожения]()
Профилировщик после нажатия кнопки уничтожения (вы можете видеть, что я больше не могу найти экземпляр leaker, тогда как он должен быть там).
![Профилировщик после нажатия кнопки уничтожения]()
И вот консоль, setInterval все еще находится в действии, хотя профайлер показывает нам, что больше нет экземпляров Leaker.
![Консоль и setInterval]()
Я что-то упустил на пути сбора мусора или профилировщика Chrome?
Ответы
Ответ 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);
})()