AS3变量或预定义的堆栈限制是5287吗?

Mar*_*rty 10 actionscript-3

我刚才做了一个测试:

function overflow(stack:int = 0):void
{
    if(stack < 5290)
    {
        trace(stack);
        overflow(stack + 1);
    }
}

overflow();
Run Code Online (Sandbox Code Playgroud)

这总是在5287调用后抛出StackOverflow错误.

错误#1023:发生堆栈溢出.

这个限制是变量(取决于机器规格,环境等)还是在某处定义的平坦值?如果我将if语句更改为小于5287,我不会收到错误.

Ves*_*per 2

显然它是可变的。由于您真正执行的所有计算都位于堆栈中(反汇编报告代码显示pushbyte指令和其他与堆栈一起使用的内容,如非操作数算术),因此该值仅报告可以将多少个函数上下文放入堆栈中,直到堆栈溢出。

我决定根据巴里斯评论中引用的这篇文章来运行一些递归阈值测试。结果相当尴尬。测试环境:FlashDevelop 3.3.4 RTM,Flash播放器调试器10.1.53.64,flash编译模式:release。“调试”模式基本上没有改变数字,也检查了这一点。

Locals number     Iterations (static int)       Iterations (Math.random())   
0                 5306                          
1                 4864                          4856
2                 4850                          4471
3                 4474                          4149
4                 4153                          3870
5                 3871                          3868
6                 3869                          3621
7                 3620                          3404
8                 3403                          3217
9                 3210                          3214
10                3214                          3042
11                3042                          3045
10 mixed          3042     1 value was assigned Math.random() and 9 - static int
10 advancedRandom 2890     1 value was assigned a custom random with 1 parameter
Run Code Online (Sandbox Code Playgroud)

请注意,所有这些值在后续执行之间的变化幅度都在 10 以内。“static int”和“Math.random()”是分配给递归调用函数中的局部变量的名称。然而,这使我做出以下假设:

  1. 将函数调用包含到递归函数中会添加到函数上下文中
  2. 局部变量的内存是与其类型一起分配的,以超过 8 个字节的块的形式分配,因为添加局部变量并不总是会减少递归限制
  3. 对某个函数添加多个调用不会为函数上下文添加更多内存
  4. “内存块”很可能有 16 个字节长,因为这个值是 2^N,添加一个 int 或 Number local 并不总是会减少递归,而且这个长度超过 8,因为 Number 变量的原始值采用8 个字节,为双精度浮点数。
  5. 假设 #4 是正确的,函数上下文大小的最佳值似乎是 172 字节,总堆栈大小为 912632 字节。这在很大程度上证实了我最初的假设,即 Flash 10 中的堆栈大小实际上为 1 MB。当我尝试在其调试器中打开测试 SWF 时,Flash 11 显示了更高的数字,但我没有对其进行广泛的测试。