2016-11-06 76 views
5

如果我有以下代码:是否有必要使垃圾收集的原始值无效?

function MyClass() { 
    this.data = { 
     // lots of data 
    }; 
} 

var myClassInstace = new MyClass(); 

var myobj = { 
    num:123, 
    str:"hello", 
    theClass:myClassInstance 
}; 

我知道这是绝对必要的事情:

myobj.theClass = null; 

要释放myClassInstance及其data财产GC。但是,我应该怎么处理myobj.nummyobj.str?我是否也必须给他们价值null?他们原始的事实是否改变了有关GC的任何事情?

+0

你想保留'myobj'但要确保其所有值不占用内存或者你想完全从记忆抹'myobjt'? – vlaz

+0

“我知道这是绝对必要的事:'myobj.theClass = NULL;'...” **不,这不是** –

+0

是的,我要刮净'myobj'。如果我想要**那**,我非常肯定,如果我不想导致内存泄漏,那么必须执行'myobj.theClass = null'。 –

回答

3

实现垃圾收集将能够尽快值不再从代码可达收集项目的JavaScript运行。这对于对象引用以及基元都是如此。收集项目的确切时间的细节因实现而异,但甚至没有必要将对象引用设置为null(如您所述),除非您需要早于当前函数的自然终止清理对象。

这一切都关系到的“范围”和作用域链的基本概念。当物品不再处于任何其他物体范围链中时,可以收集物品。清楚地理解这个问题将回答这个问题,也有助于理解闭包,这些情况是物品在内存中的停留时间比您预期的要长。

+1

说Javascript使用引用计数是不正确的。首先,JavaScript是一种语言,而不是实现。不同的实现可能使用不同类型的垃圾收集。其次,V8至少不使用引用计数,它使用具有标记和扫描算法的分代收集器。 http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection –

+0

@JustinBlank更新了我的答案。 –

+0

很酷。这是一个很好的答案。 –

0

设置为undefined(NOT NULL)将工作然而delete是更好的例子delete myobj.theClass

只是为了避免误解,我会说,有没有办法真正从内存在JavaScript中删除的对象。你删除它的引用或将它们设置为undefined,以便GC可以完成它的工作并真正删除。

+0

@Karpak U不理解问题而不是答案, –

1

有很多的“这取决于在这里”,从你的代码是做给你在运行的浏览器。但是,如果你的目标是JIT编译没有使用地图为它的属性,那么数字应该是一个8字节的double内联存储在对象内部。否定它将无能为力。

字符串和myclass实例将是一个指向分配给对象之外的内存的指针(因为一个字符串可以是任意多个字节,它不能存储在对象中,编译器可能会存储一个字符串实例在内存中并且从不释放它)。将它们删除可以允许垃圾收集器在主对象超出作用域之前释放它们。

然而,真正的问题是,为什么你担心这一点。除非您已将代码进行概要分析并将垃圾收集或内存泄漏确定为问题,否则您不应尝试优化GC行为。特别是,除非你的对象本身长期存在,否则你不应该担心置零字段。 GC在超出范围时将收集它。