使用我最近发现的chrome开发工具,我使用模块化概念的应用程序将一些Module对象留在内存中,即使它们没有被我的任何其他应用程序对象直接引用。
这里的问题似乎是,它们在某些函数范围中被引用。
正如您在以下屏幕截图中看到的那样:
在功能范围内有很多引用。
以下是代码的一小部分,演示了在我的应用程序中如何发生这种情况的方法之一。由于在module
内引用了someCallback
,因此我无法删除自己的引用。
function augmentModule(core, module){
var someCallback = function(){
module.stop();
};
module.listenTo(core, "someEvent", someCallback);
}
我的问题是:
这是一个真正的内存泄漏我不得不担心,或者这个对象是否会在以后的JavaScript引擎中被垃圾收集? JavaScript引擎是否知道“此对象仅从函数和闭包范围引用,并且没有”真实“引用,因此我可以将其删除。” ?
答案 0 :(得分:2)
一种方法是在模块子条目(augmenModule)中实现拆解方法。拆卸方法将取消绑定在初始化时由类设置的所有观察器函数。在处置对象以释放引用时调用您的拆解方法,并允许对相关内存进行垃圾回收。
答案 1 :(得分:2)
在您的示例中,没有实际问题。变量“模块”是从函数引用的,因此只要函数由某人保存,它就会被保留。这是绝对合法的,因为一旦调用它,你的函数就需要这个对象。当您的功能发布时,此引用将会继续。
然而,你应该意识到更微妙的事情。如果你应该在main函数中有几个闭包,它们都共享一个作用域存储。这意味着,某些引用可以保存在闭包中,甚至不需要它们:
function m(ref0, ref1, ref2, ref3) {
var cb1 = function(){
return ref1 + ref2;
};
function notCurentlyUsed(){
return ref2 + ref3;
};
ref0.doSomething();
return cb1;
}
所以,
请注意,您可以观看开发人员工具实际保存的内容,因为函数值会公开它。
答案 2 :(得分:0)
请展开最小距离的最顶层固定器的树。 实际上,这棵树是图形的一部分,可以让你的物体保持活力。
因此,您应该通过设计您的应用程序找出保留器树中应该存活的对象,该应用程序直接或间接地保留对必须收集的“模块”对象的引用。这个参考将是问题的根源。你有很多这样的参考。在这种情况下,你必须消除所有这些。