我写了一个静态的外“面”和动态内容部分的Web应用程序。 动态内容部分有很多的更新,用户导航系统。 当一个新的内容块被加载时,它也可任选地加载另一个JavaScript文件。 在好管家的名字,我删除了适用于旧的内容块的DOM脚本块,因为您的JavaScript不再需要。
问题就来了下,当我意识到虽然我已经删除了<script>
从DOM,先前评估的JavaScript的元件仍然可用于执行。 这使得当然有道理的,但我很担心,这可能会导致内存泄漏,如果用户浏览了很多不同的部分。
接下来的问题,是我应该担心这种情况? 如果是这样,有没有办法强制浏览器清除陈旧的JavaScript?
<theory>
你可以用更多的面向对象的方法去,并建立的方式,JavaScript的各个块来作为自己的对象模型,用自己的方法。 在卸载它,只需设置对象null
。 </theory>
(这是相当现成的袖口。)
内存使用确实需要与现有技术的当前浏览器的状态予以关注,但除非我们在谈论颇多的代码,我不知道代码的大小是问题的问题(这通常是DOM大小,以及吃剩的事件处理程序)。
你可以用一种模式,您可加载模块,将使其更容易卸载它们连接质量-或者至少,让浏览器知道它可以卸载它们。
考虑:
window.MyModule = (function() {
alert('This happens the moment the module is loaded.');
function MyModule() {
function foo() {
bar();
}
function bar() {
}
}
return MyModule;
})();
这定义了包含功能的闭合foo
和bar
,其可以相互调用以正常方式。 需要注意的是代码之外的功能立即运行。
只要你不传递出任何引用到封闭到外它里面什么什么的,然后window.MyModule将是该关闭和它的执行上下文的唯一参考。 要卸载它:
try {
delete window.MyModule;
}
catch (e) {
// Work around IE bug that doesn't allow `delete` on `window` properties
window.MyModule = undefined;
}
这告诉你没有使用该属性了JavaScript环境,使任何它引用可进行垃圾回收。 何时以及是否该集合发生显然是实现相关的。
请注意,如果你钩模块内的事件处理程序卸载之前解开他们来说,这将是非常重要的。 你可以做到这一点返回到构函数而不是主关闭一个参考:
window.MyModule = (function() {
alert('This happens the moment the module is loaded.');
function foo() {
bar();
}
function bar() {
}
function destructor() {
// Unhook event handlers here
}
return destructor;
})();
摘钩则是:
if (window.MyModule) {
try {
window.MyModule();
}
catch (e) {
}
try {
delete window.MyModule;
}
catch (e) {
// Work around IE bug that doesn't allow `delete` on `window` properties
window.MyModule = undefined;
}
}
如果您保存在命名空间,如评估的代码:
var MYAPP = {
myFunc: function(a) { ... }
}
“解放出来”整个事情应尽可能设置MYPP一些随机值一样简单,ALA
MYAPP = 1
这不依赖于有被引用变量,它是不平凡的任何其他手段
如何在JS文件加载到iframe? 然后(在理论上,从来没有测试它自己),你可以从DOM中删除的iframe,并删除了“记忆”它的使用。
我想......或者我希望...
如果你担心内存泄漏,那么你将要进行一定会出现在代码中没有事件处理要移除指的是仍然存在的DOM树。
这可能是你需要保持所有事件处理程序添加代码的列表,和卸载之前,都要经过和删除事件处理程序。
我从来没有做过这样的说法,我总是担心,当我删除节点,仍然有一个参考。
这里是JavaScript的内存泄漏的好文章: http://javascript.crockford.com/memory/leak.html
JavaScript解释器有垃圾收集器。 换句话说,如果你不引用任何东西,它不会让他们周围。
其中一个原因是良好的使用JSON与一个回调函数(JSONP)的原因。
例如,如果每个JS你的HTTP响应是:
callback({status: '1', resp: [resp here..]});
如果回调()不创建的JSON对象的引用传递作为一个参数,它会被垃圾功能完成后收集。
如果你真的需要做一个参考,那么你可能需要的数据围绕出于某种原因 - 否则,你会/不应该摆在首位引用它。
提到命名对象的方法只是创建将一直持续到引用计数到达0。换句话说参考,你要跟踪每个参考,并稍后删除它,这是很难当你有倒闭和引用从DOM说谎周围。 只是一个参考值将保持对象在内存中,和一些简单的操作可能没有你意识到这一点创建引用。
尼斯讨论。 清除了很多东西。 我还有一个担心。
如果我绑定window.MyModule.bar()一个事件,如果不小心被window.MyModule后触发该事件被删除,会发生什么? 对我来说,命名空间和分离JS成动态加载的模块的整点是为了避免误触发的事件处理程序的跨模块。
例如,如果我这样做(原谅我的jQuery):
$(”。一些一流)点击(window.MyModule.bar);
会发生什么,如果我删除window.MyModule,加载另一个模块,然后单击该意外呼吁一些类一类的元素呢?