这样做可以吗?:
function mygetTime()
{
var d = new Date();
return(d.getTime());
}
function wasteSomeMemory()
{
var temp;
for(var count = 0; count < 1000000; count += 1)
{
temp = mygetTime();
}
}
调用wasteSomeMemory()
会导致内存泄漏吗?
这个怎么样:
function wasteSomeMemory2()
{
var temp;
for(var count = 0; count < 1000000; count += 1)
{
temp = new Date();
}
}
调用wasteSomeMemory2()
会导致内存泄漏吗?我应该在for循环结束时使用delete temp;
吗?
function wasteSomeMemory2()
{
var temp;
for(var count = 0; count < 1000000; count += 1)
{
temp = new Date();
delete temp;
}
}
答案 0 :(得分:30)
new
和delete
在JavaScript中没有任何关系(尽管它们与其他语言中完全不同的构造有着令人困惑的相似性)。不要担心创建对象(new
)而不明确地清理它们,这就是垃圾收集器的工作。
new
用于通过构造函数创建对象。另一方面,delete
用于从对象中删除属性。除了作为副作用之外(例如,如果对该对象的唯一未完成引用来自您删除的属性),它与从内存中删除对象有 nothing 。
正确使用delete
:
var obj = {};
obj.foo = "bar"; // Now `obj` has a property called `foo`
delete obj.foo; // Now it doesn't
您的getmyTime
功能非常好。函数返回后,Date
对象将有资格立即回收( 回收的对象完全取决于实现)。除了有缺陷的实现之外,它不会导致内存泄漏。
您的wasteSomeMemory2
同样不会导致内存泄漏,实际上您无法调用delete temp;
- 您只能删除属性,而不能删除变量。
当你必须帮助垃圾收集器时是次,但那些通常不会(根据我的经验)与对象属性有关,所以不要涉及{{1} }。当你创建函数实例时,它们才会真正出现(如果你正在设置事件处理程序或计时器函数等,这通常很常见)。例如,考虑:
delete
因为您通过function foo() {
var listOfThings = /* ...get a list of things... */;
// ...do something with `listOfThings`...
setInterval(function() {
// ...do something that *doesn't* need `listOfThings`...
}, 1000);
}
分配给计时器的匿名函数将在函数调用中继续存在,所以它会保留对该函数调用期间范围内所有内容的实时引用(无论是否使用它) 。这样可以保留setInterval
指向内存的内容列表。如果计时器功能不需要该列表,那么这是一个问题。如果您知道该功能不需要,可以发布listOfThings
指向的列表,方法是在listOfThings
或undefined
时为null
分配listOfThings
完成它:
function foo() {
var listOfThings = /* ...get a list of things... */;
// ...do something with `listOfThings`...
listOfThings = undefined; // Done with it <== The new bit
setInterval(function() {
// ...do something that *doesn't* need `listOfThings`...
}, 1000);
}
对于事件处理函数等也是如此。无论何时创建函数,它都会“关闭”(保持实时引用)范围内定义的任何内容。因此,如果您不需要这些东西,您可以通过清除它们的引用来确保它们不会留在内存中。 (更多:Closures are not complicated)
答案 1 :(得分:4)
简短的回答是否定的。
长期的答案是我们希望上帝浏览垃圾收集器。