我一直在搞乱 Chrome 堆分析器和一些基本的 Backbone 对象,只是为了了解垃圾收集。我遇到了一些奇怪而令人困惑的行为。
使用仅加载了 jquery-1.7.2、underscore-1.3.3 和主干网 0.9.2 的基本页面。如果我从 Chrome (win/19) js 控制台窗口运行以下代码,则不会对集合进行垃圾收集。在堆分析器中,“对象的保留树”将列出 50 个用户以及模型和集合之间的循环引用,但它也会列出在 function() @234234 中显示 b 的 2。扩展这些引用,这些引用看起来来自 jQuery 的 ajax 回调处理程序。
(function () {
var collection = new Backbone.Collection();
collection.url = '/api/users/';
collection.fetch();
setTimeout(function wtf() { $('#content').append($('<div>' + collection.models[0].get('name') + '</div>')); }, 3000);
})()
如果我运行以下代码,则集合将按预期正确进行垃圾收集。不同之处在于最后一行我进行了一些随机 ajax 调用,这似乎将 jQuery ajax 回调从集合中移出。
(function () {
var collection = new Backbone.Collection();
collection.url = '/api/users/';
collection.fetch();
setTimeout(function wtf() { $('#content').append($('<div>' + collection.models[0].get('name') + '</div>')); }, 3000);
$.ajax({ url: '/api/users/' });
})()
这是预期的行为还是错误或什么?如果我有随机的对象,那会很糟糕,因为他们过去做过 ajax 请求。
更新:所以我正在进一步测试它,它似乎只影响第一个或第二个实例。如果我创建一个 setinterval 来创建一个新集合并每 1 秒调用一次 fetch,那么创建的前 1-2 个实例将无限期地保留在内存中(20 分钟以上),而创建的所有其他实例将被正确处理。
如果我调用 jquerys Ajax 函数并在成功处理程序中将数据作为创建时的参数传递给新集合,则根本不会发生此行为。创建的所有实例都已正确清理。
看来,Backbone.wrapError 函数与成功的包装一起是问题的一部分。