【发布时间】:2013-11-06 09:58:05
【问题描述】:
我创建了一个非常简单的测试用例,它创建了一个 Backbone 视图,将一个处理程序附加到一个事件,并实例化一个用户定义的类。我相信通过点击这个示例中的“删除”按钮,一切都会被清理干净,应该不会有内存泄漏。
代码的 jsfiddle 在这里:http://jsfiddle.net/4QhR2/
// scope everything to a function
function main() {
function MyWrapper() {
this.element = null;
}
MyWrapper.prototype.set = function(elem) {
this.element = elem;
}
MyWrapper.prototype.get = function() {
return this.element;
}
var MyView = Backbone.View.extend({
tagName : "div",
id : "view",
events : {
"click #button" : "onButton",
},
initialize : function(options) {
// done for demo purposes only, should be using templates
this.html_text = "<input type='text' id='textbox' /><button id='button'>Remove</button>";
this.listenTo(this,"all",function(){console.log("Event: "+arguments[0]);});
},
render : function() {
this.$el.html(this.html_text);
this.wrapper = new MyWrapper();
this.wrapper.set(this.$("#textbox"));
this.wrapper.get().val("placeholder");
return this;
},
onButton : function() {
// assume this gets .remove() called on subviews (if they existed)
this.trigger("cleanup");
this.remove();
}
});
var view = new MyView();
$("#content").append(view.render().el);
}
main();
但是,我不清楚如何使用 Google Chrome 的分析器来验证事实是否如此。堆分析器快照上显示了无数的东西,我不知道如何解码好/坏。到目前为止,我看到的教程要么只是告诉我“使用快照分析器”,要么给我一个关于整个分析器如何工作的非常详细的宣言。是否可以仅将分析器用作工具,还是我真的必须了解整个事物是如何设计的?
编辑: 像这样的教程:
据我所见,它们代表了一些更强大的材料。然而,除了介绍 3 快照技术 的概念之外,我发现它们在实践知识方面提供的很少(对于像我这样的初学者)。 '使用 DevTools' 教程没有通过一个真实的例子来工作,所以它对事物的模糊和一般的概念描述并没有太大的帮助。至于“Gmail”示例:
所以你发现了一个漏洞。现在呢?
在 Profiles 面板下半部分检查泄漏对象的保留路径
如果不能轻易推断分配站点(即事件监听器):
通过 JS 控制台检测保留对象的构造函数以保存分配的堆栈跟踪
使用闭包?启用适当的现有标志(即 goog.events.Listener.ENABLE_MONITORING)以在构造期间设置 creationStack 属性
读完之后,我发现自己更加困惑,而不是更少。再说一遍,它只是告诉我做事,而不是如何去做。从我的角度来看,那里的所有信息要么太模糊,要么只对已经了解流程的人有意义。
下面的@Jonathan Naguin's answer 提出了其中一些更具体的问题。
【问题讨论】:
-
我对在浏览器中测试内存使用情况一无所知,但如果您还没有看过,Addy Osmani's article about the Chrome web inspector 可能会有所帮助。
-
谢谢你的建议,保罗。但是,当我在单击删除之前拍摄一个快照,然后在单击它之后拍摄另一个快照,然后选择“在快照 1 和 2 之间分配的对象”(如他的文章中所建议的那样)时,仍然存在 2000 多个对象。例如,有 4 个“HTMLButtonElement”条目,这对我来说毫无意义。真的,我不知道发生了什么。
-
doh,这听起来不是特别有用。可能是使用像 JavaScript 这样的垃圾收集语言,您并不是真的要在与测试一样精细的级别上验证您正在使用内存做什么。检查内存泄漏的更好方法可能是调用
main10,000 次而不是一次,然后查看最后是否会使用更多内存。 -
@PaulD.Waite 是的,也许。但在我看来,我仍然需要进行细粒度分析来确定问题到底是什么,而不仅仅是能够说(或不说):“好吧,这里某处存在内存问题”。而且我确实觉得我应该能够在如此精细的级别上使用他们的分析器......我只是不确定如何:(
标签: javascript google-chrome backbone.js memory-leaks