避免使用 jquery 创建和删除 DOM 的对象发生内存泄漏
Avoid memory leak with objects that create and remove DOM with jquery
假设你有一个组件,其工作之一是创建一些DOM节点(例如使用jquery):
function PageFiller() {
}
PageFiller.prototype.fillPage = function () {
this.dom = $("<div/>", {
"class" : "hello",
text : "Hello world"
});
$("body").append(this.dom);
}
假设另一个组件使用它来填充 DOM,而不保留对"PageFiller"的引用
function Main() {
}
Main.prototype.start = function () {
var filler = new PageFiller();
filler.fillPage();
};
var main = new Main()
main.start();
不假设在那之后(在同一范围内),有人残酷地清除了 DOM:
$(".hello").remove();
在这种情况下的内存布局是什么?我是否泄漏了页面填充实例的内存?
我有点不确定PageFiller实例会在什么时候被垃圾回收(如果它发生的话),因为它包含一个对jquery对象的引用,该对象表示不再存在的DOM的一部分?或者它与 DOM 无关,因为据我了解,实际的 DOM 对象与常规 JS 变量位于不同的堆中(除非我在这里弄错了......
更新:事情的一个变体是,如果对PageFiller的引用由主要对象保留:
Main.prototype.start = function () {
this.filler = new PageFiller();
filler.fillPage();
}
在这种情况下,Main 对象具有对 PageFiller 对象的引用,该对象本身包含对 JQ 对象的引用;在"删除"之后,JQ 对象仍然存在于内存中,但指向不存在的 DOM 节点,对吗?
我是否正确地说,在原始示例中,一旦 main.start() 完成:
- 没有对象包含对PageFiller对象的引用,因此它被垃圾回收,并且pageFiller.dom对象没有被任何人引用,所以它也会被垃圾回收?
- 实际的 DOM 元素显然仍然存在于内存中,但在我真的不必担心的单独堆中
其他情况 :
这次有一个很小的变化,事件处理程序使事情复杂化:
PageFiller.prototype.fillPage = function () {
var self = this;
this.dom = ... // as usual
this.dom.click(function () {
alert("Just clicked on dom generated by " + self);
});
}
这一次,仅仅让 PageFiller 实例超出范围不足以回收其内存,因为它是由单击处理程序中使用的闭包引用的。我在这里泄露了记忆吗?或者我可以信任 $(").remove() 调用来终止对闭包的引用,从而杀死对 PageFiller 的最后一个引用?如果我在没有 jquery 的情况下删除元素(使用本机 DOM API?
这可能一切都像我希望的那样工作,但我只是想说服自己,没有记忆可以从这种模式中泄漏。
谢谢。
已更新
main.start()
完成后删除filler.dom
将减少它所持有的节点的引用计数,因为它不拥有节点(即弱属性)。
当您调用$().remove()
时删除实际节点时,引用计数再次减少到零,并且可以进行垃圾回收。
所以,AFAICT你应该没有什么可担心的。
- 引用对象中的通用值
- jQuery匹配JSON对象的部分文本
- 节点导出返回一个空对象
- 如何在Javascript中将JSon对象转换为数组
- 我可以在json对象中添加一个函数吗
- 使用JS将数组转换为json对象
- 全局变量和全局对象的属性之间有什么区别吗
- 简单对象的Javascript内存泄漏
- 递归Javascript对象是否会导致任何问题(内存泄漏)
- javascript删除对象,防止内存泄漏
- 避免使用 jquery 创建和删除 DOM 的对象发生内存泄漏
- 在函数中创建 jQuery 对象然后不使用它是否会产生内存泄漏
- 对象1作为对象2的属性,而对象2又是对象1的属性,这将导致内存泄漏
- ID属性为的动态DOM对象的IE9内存泄漏
- JavaScript对象的生命周期内存泄漏
- 当对象属性引用对象本身(self reference)时,Javascript内存泄漏
- 将Audio对象设置为undefined会导致内存泄漏吗?
- AJAX调用Elasticsearch导致XHR对象内存泄漏
- Javascript内存泄漏:为什么将对象分配给null会起作用
- 在闭包中使用全局对象会导致内存泄漏吗?