我对此进行了相当多的研究,但主要是通过将其他问题拼凑在一起,这仍然留下了一些疑问。在一个不随时刷新浏览器页面并且可能会运行相当长一段时间(几个小时)而不关闭的应用程序中(假设刷新页面或导航到另一个页面会重新启动 js 代码),确保对象的最佳方法是什么已释放并且没有内存泄漏。
这些是我关心的具体场景:
下面的所有代码都在揭示性模块模式内。
mycode = function(){}()
函数内的变量,我确信这个变量被 GC 收集得很好
function(){ var h = "ss";}
模块内的变量,当不再需要时应该 g = null 吗?
var g;
function(){ g = "dd";}
最后是 jqXHR 的生命周期:它返回后是否被清理?无论是否保留在函数或模块内,是否应该在所有情况下将其设置为 null 作为预防措施?
如果这样做,它返回后是否会被 GC 清理掉?:
function(){
var x = $.get();
x.done = ...;
x.fail = ...;
}
这样做的时候怎么样,x返回后它也会被清理吗?:
var x;
function(){
x = $.get();
x.done = ...;
x.fail = ...;
}
最后,有没有一种方法可以在不重新启动浏览器的情况下清理所有变量并重新启动模块?
函数内的变量,我确信这个变量被 GC 收集得很好
Yes.
模块内的变量,当不再需要时应该 g = null 吗?
Sure.
最后是 jqXHR 的生命周期:它返回后是否被清理?无论是否保留在函数或模块内,是否应该在所有情况下将其设置为 null 作为预防措施?
各种浏览器都存在与 XHR 相关的错误,导致onreadystatechange
以及它关闭后仍然无法收集的任何东西,除非开发人员小心地将其替换为虚拟值(xhr.onreadystatechange = new Function('')
)但我相信 jQuery 会为你处理这个问题。
最后,有没有一种方法可以在不重新启动浏览器的情况下清理所有变量并重新启动模块?
与页面关联的全局状态将占用浏览器内存,直到该页面从浏览器历史堆栈中逐出。location.replace可以在这里帮助您,让您终止当前页面并将其替换为同一应用程序的新版本,而无需扩展历史记录堆栈。
将当前文档替换为提供的 URL 处的文档。与的区别assign()
方法是使用后replace()
当前页面不会保存在会话历史记录中,这意味着用户将无法使用“后退”按钮导航到该页面。
当您使用“模块”一词时,该术语对于浏览器或其 JavaScript 解释器来说没有明确定义的含义,因此无法从内存中逐出模块,只能逐出模块。您必须担心以下几件事可能会将内容保留在内存中:
- 对附加到 DOM 节点的 JavaScript 对象及其关闭的所有内容的引用——事件处理程序是一个非常常见的示例。
- Live
setInterval
and setTimeout
回调以及它们关闭的所有内容。
- 全局对象的属性以及它们所覆盖的所有内容。
- 正如您所指出的,某些主机对象的属性(例如 XHR 实例、Web Worker 回调等)以及(您猜对了)它们关闭的所有内容。
任何要卸载模块且仅卸载模块的方案都需要处理所有这些,并找出其中哪些是该模块的一部分,哪些不是。这是很多不同类型的清理工作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)