信任Javascript垃圾收集器

信任Javascript垃圾收集器,javascript,garbage-collection,Javascript,Garbage Collection,我有几个例子,我的Javascript代码似乎在泄漏内存,但我不确定我应该从垃圾收集器中得到什么 例如,Firefox中运行的间隔计时器函数中的var=new Object()似乎会随着时间的推移而泄漏。有一些简单的解决方案,但我很好奇,我是应该期待垃圾收集器处理所有事情,还是应该负责帮助垃圾收集器 如果我需要帮助垃圾收集器,那么规则是什么?大多数(我相信所有)Javascript(ECMAScript)引擎都是通过一种称为“引用计数”的方法工作的。我让你来看看这个术语 简而言之,当没有任何东西

我有几个例子,我的Javascript代码似乎在泄漏内存,但我不确定我应该从垃圾收集器中得到什么

例如,Firefox中运行的间隔计时器函数中的
var=new Object()
似乎会随着时间的推移而泄漏。有一些简单的解决方案,但我很好奇,我是应该期待垃圾收集器处理所有事情,还是应该负责帮助垃圾收集器

如果我需要帮助垃圾收集器,那么规则是什么?

大多数(我相信所有)Javascript(ECMAScript)引擎都是通过一种称为“引用计数”的方法工作的。我让你来看看这个术语

简而言之,当没有任何东西指向某个对象时,该对象将被释放。。。使用它

有两件事可能会让你感觉不到有多少内存被使用

1) ECMAScript不会在系统处理完对象后立即释放该对象。垃圾收集是“根据需要”运行的。这可能有很大的不同

2) 闭包保存引用的时间比您想象的要长。意外的闭包可能会比您预期的时间长。

大多数(我相信所有)Javascript(ECMAScript)引擎都是通过一种称为“引用计数”的方法工作的。我让您看看这个术语

简而言之,当没有任何东西指向某个对象时,该对象将被释放。。。使用它

有两件事可能会让你感觉不到有多少内存被使用

1) ECMAScript不会在系统处理完对象后立即释放该对象。垃圾收集是“根据需要”运行的。这可能有很大的不同


2) 闭包保存引用的时间比您想象的要长。意外的闭包可能会比您预期的时间长。

必须将此作为一个答案,而不是长度注释:

好的——首先是术语的澄清:

如果它在计时器上运行,那么它不是递归的。然而,这是一个常见的误解

它是递归代码,函数调用本身——原始函数调用保留在堆栈上,直到整个过程最终展开并将值返回给原始调用方。使用超时时,函数的每次迭代都会在单独的执行上下文中执行

递归函数示例 函数阶乘(n){ 如果(n==1){ 返回1; }否则{ 返回n*阶乘(n-1); } }

这是/不是/递归的: 函数have(){ 设置超时(烦恼,1000); window.alert(“这会让你分秒必争!”); }

“烦恼”的每次迭代都是完全独立的。它只是为调用另一个实例设置计时器。堆栈上没有一堆“烦扰”函数,您不能向调用者返回任何内容

第二:在我给你的例子中,变量
a
没有超出范围,但是
a
引用的旧对象没有活动引用,所以它们可以自由释放。变量指向的内容可能会有所不同

var a, b;
a = {};
b = a;   // This object now has TWO references using it.

b = null;  // The object now has one reference
a = null;  // Object has no references and is free for release.
在这一点上,我能做的最好的事情就是在这里告诉你:


必须将此作为一个答案,而不是长篇大论:

好的——首先是术语的澄清:

如果它在计时器上运行,那么它不是递归的。然而,这是一个常见的误解

它是递归代码,函数调用本身——原始函数调用保留在堆栈上,直到整个过程最终展开并将值返回给原始调用方。使用超时时,函数的每次迭代都会在单独的执行上下文中执行

递归函数示例 函数阶乘(n){ 如果(n==1){ 返回1; }否则{ 返回n*阶乘(n-1); } }

这是/不是/递归的: 函数have(){ 设置超时(烦恼,1000); window.alert(“这会让你分秒必争!”); }

“烦恼”的每次迭代都是完全独立的。它只是为调用另一个实例设置计时器。堆栈上没有一堆“烦扰”函数,您不能向调用者返回任何内容

第二:在我给你的例子中,变量
a
没有超出范围,但是
a
引用的旧对象没有活动引用,所以它们可以自由释放。变量指向的内容可能会有所不同

var a, b;
a = {};
b = a;   // This object now has TWO references using it.

b = null;  // The object now has one reference
a = null;  // Object has no references and is free for release.
在这一点上,我能做的最好的事情就是在这里告诉你:


这可能对您有用:这可能对您有用:您知道在重新分配var的情况下会发生什么吗,例如:(1)var=new Object();在类似
var a的情况下;虽然(true){a={};//在该特定代码中优于新对象}
,但将创建一个对象,然后在下一个循环迭代中释放该对象以供发布。GC将在需要时运行,但没有内存泄漏。因此,在这种情况下,变量没有超出范围,但它仍然会被垃圾收集,这是有道理的,但我没有看到任何关于GC如何工作的描述来解释这种情况,或者我只是缺少算法的这一部分?顺便说一句,这不仅仅是理论上的。我有正在泄漏的JS代码,我怀疑在计时器上运行的递归代码中有多个var a=new object()。我可以更改代码,但它当前的工作方式更方便。您知道在重新分配var的情况下会发生什么吗,例如while(1)var=newobject();在类似
var a的情况下;虽然(true){a={};//在该特定代码中优于新对象}
,但将创建一个对象,然后在下一个循环迭代中释放该对象以供发布。GC将在需要时运行,但没有内存泄漏。因此,在本例中,变量没有超出作用域,但它仍然会被垃圾收集,这是有道理的,但我还没有看到任何关于如何