如何找出 Javascript 堆栈何时已满?

How to find out when the Javascript stack gets full?

我有一个算法,它以相对较深的方式递归工作,因此最终会发生超出最大堆栈大小的异常(而不是无休止的递归!)。

我的算法可以自行拆分,使用 asap 进行异步处理,但是每次都这样做会大大减慢执行速度。我想要一种(快速)方法来找出当前的堆栈使用百分比,这样我的算法可以决定在低于 90% 时同步继续,但在高于 90% 时异步继续。我知道这个值必须在内部,但是有没有办法访问它?

另一方面,我可以想象捕获超出最大堆栈大小的错误,但我认为这是不可能的(为什么不呢?抛出此异常将意味着返回给调用者,这应该实际上减少了堆栈大小并且旧的堆栈条目应该仍然完好无损???)

当然,一种方法是通过我的所有函数传递一个计数器变量,但这很尴尬。也不清楚,我的堆栈在 90% 时的计数器值是多少,因为我不知道堆栈有多大以及我的每个堆栈帧有多大。

所以实际上 JavaScript 在这种情况下似乎天生就是失败的,即使程序员可以避免它,如果他能够访问他需要的信息 - 这些信息存在于某处但由于未知原因保密?

这取决于浏览器。你的方法不是解决问题的最佳选择,我们当然不能向用户宣布“你的要求太重,我们无法处理”。 另一种方法是反递归算法,所有递归解决方案总会有一个对应的非递归解决方案。你可以自己模拟一个栈,而不是系统栈,实现循环查找结果。

如果不通过传递变量或可能引用共享状态来自己跟踪,就无法测量当前堆栈利用率。

但是您可以在调用堆栈满时捕获调用堆栈溢出错误。 (您链接的不清楚的问题是在谈论其他事情,。)您可以使用它来大致了解可用的堆栈大小,但可能不能保证不同函数的一致性取决于优化和东西。

var maxDepth = 0;
function popTheStack() {
  maxDepth++;
  popTheStack();
}

try {
  popTheStack();
} catch (ex) {
  console.log("caught " + ex + " at depth " + maxDepth);
}