这样做可以吗?
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()造成内存泄漏?我应该使用delete temp吗在for循环结束?
function wasteSomeMemory2() { var temp; for(var count = 0; count < 1000000; count += 1) { temp = new Date(); delete temp; } }
解决方法
新的和删除在JavaScript中没有任何关系(尽管它们与其他语言中完全不同的结构混淆).不要担心创建对象(新的)而没有明确地清理它们,那就是垃圾收集器的工作.
new是通过构造函数创建对象.另一方面,删除用于从对象中删除属性.除了作为副作用(例如,如果唯一未被提到的对象的引用来自您删除的属性),它与从内存中删除对象无关.
正确使用删除的示例:
var obj = {}; obj.foo = "bar"; // Now `obj` has a property called `foo` delete obj.foo; // Now it doesn't
你的getmyTime函数是完美的. Date对象在函数返回后(将被回收完全归结为实现)将有资格立即回收.它不会导致内存泄漏,除了有bug的实现.
你的wasteSomeMemory2同样不会造成内存泄漏,实际上你不能调用delete temp; – 你只能删除属性,而不是vars.
有时你必须帮助垃圾收集器,但通常不会(在我的经验中)与对象属性有关,所以不涉及删除.当你创建函数实例(这是很经常的,如果你正在设置事件处理程序或定时器函数等),他们才真正出现.例如,考虑:
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在内存中指向的内容.如果定时器功能不需要该列表,那就是一个问题.如果您知道该函数不需要它,可以通过在完成以下操作时分配undefined或null或者将其中的任何内容分配给listOfThings,即可释放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)