JavaScript对象的生命和内存泄漏

Ton*_*llo 9 javascript jquery memory-leaks

我已经对此进行了相当多的研究,但主要是将其他问题拼凑在一起,这仍然存在一些疑问.在一个不会随时刷新浏览器页面的应用程序中,可能会在不关闭的情况下生存很长时间(小时)(假设刷新页面或导航到另一个页面会重新启动js代码),确保对象的最佳方法是什么释放并且没有内存泄漏.

这些是我关注的特定场景:

下面的所有代码都在一个揭示模块模式中.

mycode = function(){}()
Run Code Online (Sandbox Code Playgroud)

函数中的变量,我确信GC收集的这个很好

function(){ var h = "ss";}
Run Code Online (Sandbox Code Playgroud)

模块中的变量,当不再需要g = null时?

var g;
function(){ g = "dd";}
Run Code Online (Sandbox Code Playgroud)

最后是jqXHR的生命:它在返回后是否被清理干净了?在所有情况下是否应将其设置为null作为预防措施是否保留在函数或模块中?

如果这样做,它返回后是否被GC清理了?:

function(){
   var x = $.get();
   x.done = ...;
   x.fail = ...;
}
Run Code Online (Sandbox Code Playgroud)

这样做的时候,它会在x返回后被清理掉吗?:

var x;
function(){
   x = $.get();
   x.done = ...;
   x.fail = ...;
}
Run Code Online (Sandbox Code Playgroud)

最后,有没有办法清理所有变量并重新启动模块而无需重新启动浏览器?

Mik*_*uel 7

函数中的变量,我确信GC收集的这个很好

是.

模块中的变量,当不再需要g = null时?

当然.

最后是jqXHR的生命:它在返回后是否被清理干净了?在所有情况下是否应将其设置为null作为预防措施是否保留在函数或模块中?

各种浏览器都有与XHR相关的错误导致它onreadystatechange和它关闭的任何东西保持无法收集,除非开发人员小心地用虚拟值替换它(xhr.onreadystatechange = new Function(''))但我相信jQuery会为你处理这个问题.

最后,有没有办法清理所有变量并重新启动模块而无需重新启动浏览器?

与页面关联的全局状态将占用浏览器内存,直到页面从浏览器历史堆栈中逐出. location.replace通过让您终止当前页面并将其替换为同一应用程序的新版本而不扩展历史堆栈,可以帮助您.

将当前文档替换为提供的URL处的文档.与该assign()方法的不同之处在于,使用replace()当前页面后将不会保存在会话历史记录中,这意味着用户将无法使用"后退"按钮导航到该页面.

当您使用"模块"一词时,这不是一个对浏览器或其JavaScript解释器具有明确定义的术语,因此无法从内存中驱逐模块和模块.您可能需要担心的一些事情可能会让事情记忆犹新:

  1. 引用已附加到DOM节点的JavaScript对象及其关闭的所有内容 - 事件处理程序是一个非常常见的示例.
  2. 直播setIntervalsetTimeout回调以及他们关闭的所有内容.
  3. 全局对象的属性以及它们关闭的所有内容.
  4. 正如您所指出的,某些主机对象的属性,如XHR实例,Web工作者回调等,以及(您猜对了)它们关闭的所有内容.

任何要卸载模块的方案,只有一个模块需要处理所有这些,并找出哪些是模块的一部分,哪些不是.这是很多不同类型的清理.