内存问题调用setTimeout()到我调用它的函数?

时间:2017-10-27 17:44:34

标签: javascript

我有以下功能:

var counter = 0;

test();

function test() {
    counter++;
    alert(counter);
    setTimeout(function() { test() }, 100);
}

这会产生内存问题吗? ie:test()函数会在setTimeout()再次调用之前正常退出吗?

我的测试显示它在再次调用函数之前确实退出,但是同事确定它会导致内存问题。

更新: 我在Chrome上运行测试并观看了其任务管理器,内存使用情况没有变化。

testSetTimeout(0);

function testSetTimeout(a) {
    $("body").html(a);
    var v = new Array();
    for (var i = 0; i < 20000; i++)
        v.push("abcdefghijklmnopqrstuvwxyz");
    setTimeout(function () { testSetTimeout(a + 1); }, 0);
}

但是,当更改此代码直接调用testSetTimeout()时,它会执行大约8000次,然后在Chrome中执行。

3 个答案:

答案 0 :(得分:0)

你应该没事,因为对test()的调用将被放在setTimeout函数的调用堆栈上,而不是test(),所以你不会爆炸堆栈

答案 1 :(得分:0)

每次调用<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical"> <LinearLayout android:id="@+id/container1" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_marginBottom="8dp" android:layout_marginEnd="10dp" android:layout_marginStart="10dp" android:layout_marginTop="8dp" android:background="@drawable/bg_chip_view" android:orientation="horizontal"> <com.litedevs.movieconic.utils.ClockView android:id="@+id/chip_clock" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/ic_circle" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/chip_text" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:paddingEnd="10dp" android:paddingLeft="5dp" android:paddingRight="10dp" android:paddingStart="5dp" android:text="2:00 PM" android:textColor="@color/colorAccent" /> </LinearLayout> <LinearLayout android:id="@+id/container2" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_marginBottom="8dp" android:layout_marginEnd="10dp" android:layout_marginStart="10dp" android:layout_marginTop="8dp" android:background="@drawable/bg_chip_view" android:orientation="horizontal"> <com.litedevs.movieconic.utils.ClockView android:id="@+id/chip_clock" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/ic_circle" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/chip_text" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:paddingEnd="10dp" android:paddingLeft="5dp" android:paddingRight="10dp" android:paddingStart="5dp" android:text="2:00 PM" android:textColor="@color/colorAccent" /> </LinearLayout> <LinearLayout android:id="@+id/container3" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_marginBottom="8dp" android:layout_marginEnd="10dp" android:layout_marginStart="10dp" android:layout_marginTop="8dp" android:background="@drawable/bg_chip_view" android:orientation="horizontal"> <com.litedevs.movieconic.utils.ClockView android:id="@+id/chip_clock" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/ic_circle" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/chip_text" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:paddingEnd="10dp" android:paddingLeft="5dp" android:paddingRight="10dp" android:paddingStart="5dp" android:text="2:00 PM" android:textColor="@color/colorAccent" /> </LinearLayout> <LinearLayout android:id="@+id/container4" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_marginBottom="8dp" android:layout_marginEnd="10dp" android:layout_marginStart="10dp" android:layout_marginTop="8dp" android:background="@drawable/bg_chip_view" android:orientation="horizontal"> <com.litedevs.movieconic.utils.ClockView android:id="@+id/chip_clock" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/ic_circle" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/chip_text" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:paddingEnd="10dp" android:paddingLeft="5dp" android:paddingRight="10dp" android:paddingStart="5dp" android:text="2:00 PM" android:textColor="@color/colorAccent" /> </LinearLayout> <LinearLayout android:id="@+id/container5" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_marginBottom="8dp" android:layout_marginEnd="10dp" android:layout_marginStart="10dp" android:layout_marginTop="8dp" android:background="@drawable/bg_chip_view" android:orientation="horizontal"> <com.litedevs.movieconic.utils.ClockView android:id="@+id/chip_clock" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/ic_circle" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/chip_text" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:paddingEnd="10dp" android:paddingLeft="5dp" android:paddingRight="10dp" android:paddingStart="5dp" android:text="2:00 PM" android:textColor="@color/colorAccent" /> </LinearLayout> </LinearLayout> 时,都会创建一个新实例。该实例必须与调用它的位置保持关系,否则它将成为“僵尸”。每当你在代码中有一个自我复制的僵尸时,它就不是一个好的代码。另一方面,如果它不成为僵尸并保持对它的调用位置的引用,则会发生意外的递归,这基本上是内存泄漏。这样做的正确方法是没有浪费内存:

test()

答案 2 :(得分:-1)

是的,正如您所说,它会导致内存问题。当var counter = 0; test(); function test() { counter++; if(counter >20) return; // This will make the function to exit. setTimeout(function() { test() }, 100); } 第一次调用时{{1}}将保持初始触发的范围。每次函数调用都会将{{1}}保留在堆栈中,并且由于堆栈已满而导致内存泄漏。

{{1}}