【问题标题】:How to find out when the Javascript stack gets full?如何找出 Javascript 堆栈何时满?
【发布时间】:2017-06-24 05:03:07
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 请展示你的作品。这听起来像是您的算法的问题,而不是 javascript 解释器如何运行它。你在做什么?节点还是浏览器?你的算法甚至试图完成什么?我们需要这些细节。
  • 我无法提供“算法”——它处理数据并根据数据递归地构建自己。我的算法没有问题。当数据结构嵌套足够深时,实际上会发生这种情况,堆栈会在没有无限递归的情况下运行。
  • 如果你的递归太深以至于溢出堆栈,你需要重写你的算法,所以做短尾递归。
  • 那是在我的问题中写的 - 我知道这一点。我可以分裂,这只是“何时”的问题。但是由于您可以捕获超出最大调用堆栈的异常,“何时”现在变得很容易......
  • 处理这个问题的方法太可怕了;正确编写算法;不要依靠古怪的系统怪癖来应对您的低效率。以防御性的方式写作,而不是冒犯性地写作。

标签: javascript stack-overflow


【解决方案1】:

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

但是您可以在调用堆栈溢出错误已满时捕获它。 (您链接的不清楚的问题是在谈论其他内容,@ 987654321@。)您可以使用它来粗略了解可用堆栈大小,但这可能不能保证对于不同的功能是一致的,具体取决于优化和东西.

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

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

【讨论】:

  • 没有很好地阅读其他问题。我会做一个 jsperf,看看在我的算法中引入 try catch 块对性能有多大影响。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2013-01-11
    • 1970-01-01
    • 2017-08-04
    • 2010-10-10
    • 1970-01-01
    • 2018-12-07
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多