【问题标题】:`new` without `delete` on same variable in JavascriptJavascript中同一变量上的“new”没有“delete”
【发布时间】:2011-02-02 00:53:35
【问题描述】:

这样可以吗?:

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;
    }
}

【问题讨论】:

    标签: javascript object garbage-collection new-operator


    【解决方案1】:

    newdelete 在 JavaScript 中彼此没有任何关系(尽管它们与其他语言中完全不同的结构相似令人困惑)。不要担心在没有明确清理对象的情况下创建对象 (new),这是垃圾收集器的工作。

    new 用于通过构造函数创建对象。另一方面,delete 用于从对象中删除属性。它与从内存中删除对象没有任何关系,除了作为副作用(例如,如果对该对象的唯一未完成引用来自您删除的属性)。

    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;——你只能删除属性,不能删除变量。


    次您必须帮助垃圾收集器,但这些通常与对象属性无关(根据我的经验),因此不涉及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 指向的列表,方法是在完成后将undefinednull 或其他任何东西分配给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

    【讨论】:

      【解决方案2】:

      简短的回答是否定的。

      长答案是我们希望上帝浏览器垃圾收集器捡起这个。

      【讨论】:

        猜你喜欢
        • 2021-09-13
        • 2020-09-29
        • 1970-01-01
        • 2011-05-27
        • 1970-01-01
        • 1970-01-01
        • 2015-01-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多