JavaScript堆栈管理/释放内存

时间:2012-12-02 10:04:11

标签: javascript performance

在定义类时:

var namespace = {};
namespace.appleClass = function() {
   this.collection = [];
};

namespace.appleClass.prototype.methodOne = function(arg) {
   this.collection.push(arg);
};

摆脱this.collection的方法很简单。

this.collection.length = 0;

我的问题是上面定义的方法会发生什么(在namespace.appleClass.prototype上)。 JavaScript如何处理它们?函数“存储”在哪里?如何释放存储空间?

上述课程可以这样使用。

var apple = new appleClass();
appleClass.methodOne(2);
appleClass.collection[0]// will be equal to two etc..

我知道如何清空DOM引用,COM引用和删除操作符背后的长篇故事。我不知道的是从“自定义原型”或“类”中删除函数和引用它们的最佳方法是什么。

2 个答案:

答案 0 :(得分:2)

  

摆脱this.collection的方法很简单。

this.collection.length = 0;

这没有摆脱数组,只是截断它,所以它没有条目。要实际完全摆脱数组,请执行delete this.collection(这将删除完全引用数组的属性,使数组符合垃圾回收条件)或this.collection = null(将释放对数组的引用) ,使其符合垃圾收集的条件,但删除该属性,该属性仍然存在,值为null)。

this.collection中任何未在其他地方引用的内容都有资格进行垃圾回收。何时(或实际上是否)发生这完全取决于JavaScript实现。

这是关键点,真的:要在JavaScript中“管理”内存,你只需要确保没有任何东西指的是你不再需要的东西。通常,这仍然不属于您的应用程序逻辑(您不再需要它,因此您放弃对它的引用)。如果您在设计代码时牢记how closures work,那么在大多数情况下,您无需担心内存管理。

在问题评论中重新提问:

  

我正在考虑namespace.appleClass.prototype下找到的方法。 JavaScript如何处理它们?函数“存储”在哪里?如何释放存储空间?

函数对象存储在堆中(几乎可以肯定;如果只是局部变量引用,像Google的V8这样的引擎可能会使用堆栈);代码所在的位置取决于实现。对函数对象(及其代码)的引用存储在prototypeappleClass对象的属性中。这些函数中只有一个由new namespace.appleClass通过原型链创建的所有实例共享。每个实例都有函数的单独副本(只是对它的单独引用),因此无需担心在实例上“清理”该函数。

如果您不再需要 >,则代码中的任何位置(例如,所有 appleClass实例不再需要它),您可以获得通过delete namespace.appleClass.prototype.methodOne)摆脱它。这将删除原型中的属性,该原型释放对函数对象的引用,该对象释放对函数代码的引用,所有这些引用都符合垃圾回收的条件。但这非常不寻常,单个函数在任何情况下都不会占用太多内存。

答案 1 :(得分:0)

将变量设置为null可确保破坏对所有浏览器中对象的任何引用,包括在DOM元素和Javascript范围之间进行循环引用。 通过使用delete命令,我们在下一次运行Garbage集合时标记要清除的对象,但是如果有多个变量引用同一个对象,则删除单个变量将不会释放该对象,它只会删除该变量与对象之间的联系。在下一次运行垃圾收集时,只会清除变量。