为什么最大调用堆栈大小因样本而异?

Why does the maximum call stack size differ from sample to sample?

如果我尝试

var count = 0

function recurse() {
  count++
  recurse()
}

try {
  recurse()
} catch(e) {
  console.log(e.message, count)
}

结果是Maximum call stack size exceeded 15662,但如果我尝试

var count = 0

function recurse() {
  count++
  ( new Function( recurse.toString().split('\n').splice(1, 2).join('\n') ) )()
}

try {
  recurse()
} catch(e) {
  console.log(e.message, count)
}

那么结果就是Maximum call stack size exceeded 8862.

为什么数字不同?

啊,根据http://2ality.com/2014/04/call-stack-size.html

the number of recursive calls you can make depends on two quantities: the size of the stack and the size of the stack frame (holding parameters and local variables).

因为堆栈不完全属于您的程序。

例如,当你的程序是运行时,可以处理异步中断,或者你的任务可以被调度器挂起,CPU切换到另一个任务。如果是这样,您任务的当前上下文(寄存器、PSW)将保存在堆栈中,并在您重新获得控制权时恢复。

结果:堆栈消耗可能会有所不同,并且堆栈指针 (SP) 以下的所有值都未定义。如果你保存低于 SP 的内容,而不是事实,你将读取相同的内容。

因为在第一种情况下,每个递归函数调用的机器代码的大小较小。商(堆栈大小/堆栈上的函数调用大小)更大。