如果我有以下代码:
function MyClass() {
this.data = {
// lots of data
};
}
var myClassInstace = new MyClass();
var myobj = {
num:123,
str:"hello",
theClass:myClassInstance
};
我知道这是绝对必要的:
myobj.theClass = null;
为GC释放myClassInstance
及其data
属性。但是,我应该如何处理myobj.num
和myobj.str
?我是否必须给它们null
的价值?他们原始的事实是否改变了关于GC的任何事情?
答案 0 :(得分:5)
实现垃圾收集的JavaScript运行时将能够在代码无法再访问值时立即收集项目。这对于对象引用和原语都是如此。收集项目的确切时刻的详细信息因实现而异,但甚至不需要将对象引用设置为null(如您所述),除非您需要比当前函数的自然终止更早地清理对象。 / p>
这一切都与"范围"的基本概念联系在一起。和范围链。当项目不再位于任何其他对象范围链中时,可以收集该项目。清楚地理解这一点将回答这个问题,也有助于理解闭包,这些场景中的项目在内存中的时间比你预期的要长。
答案 1 :(得分:1)
有很多“它取决于此处”,从您的代码所做的操作到您正在运行的浏览器。但是,如果您的对象是JIT编译为不使用地图的属性,那么数字应该是一个8字节的双重内存存储在对象内部。否定它将无能为力。
字符串和myclass实例将是指向在对象外部分配的内存的指针(因为字符串可以是任意多个字节,它不能存储在对象内。编译器可以设想存储字符串的一个实例)然而,永远不会释放它。在主对象超出范围之前,将它们取消可以允许垃圾收集器释放它们。
然而,真正的问题是你为什么担心这个问题。除非您已将代码分析并将垃圾收集或内存泄漏识别为问题,否则您不应尝试优化GC行为。特别是,除非您的myobj
对象本身将长时间存在,否则您不必担心将字段置零。当GC超出范围时,GC将收集它。
答案 2 :(得分:0)
设置为undefined
(非空)可行但delete
更好的示例delete myobj.theClass
为了避免误解,我会说在JavaScript中没有办法真正从内存中删除对象。您删除它的引用或将它们设置为未定义,以便GC可以执行此操作并真正删除。