超出最大调用堆栈大小错误

IT技术 javascript html webkit callstack dwr
2021-02-02 07:47:20

我正在使用 Direct Web Remoting (DWR) JavaScript 库文件,并且仅在 Safari(桌面和 iPad)中出现错误

它说

超出了最大调用堆栈大小。

这个错误究竟是什么意思,它是否完全停止处理?

还有Safari浏览器的任何修复(实际上在iPad Safari,它说

JS:执行超过超时

我假设是相同的调用堆栈问题)

6个回答

这意味着在您的代码中的某个地方,您正在调用一个函数,该函数又调用另一个函数,依此类推,直到达到调用堆栈限制。

这几乎总是因为没有满足基本情况的递归函数。

查看堆栈

考虑这个代码...

(function a() {
    a();
})();

这是几次调用后的堆栈...

网络检查员

如您所见,调用堆栈会不断增长,直到达到一个限制:浏览器硬编码堆栈大小或内存耗尽。

为了修复它,请确保您的递归函数具有能够满足的基本情况......

(function a(x) {
    // The following condition 
    // is the base case.
    if ( ! x) {
        return;
    }
    a(--x);
})(10);
您的代码运行相同的低效段 134217728 次。别开玩笑了,它很慢。您应该使用按位运算符,以便可以将 9 级循环展开为一级循环。
2021-03-15 07:47:20
@Akhoy 在常规函数中是的,但请考虑递归函数。它调用另一个(它自己)并将前者的返回地址留在堆栈上(否则 PC 会知道去哪里?)这当然会再次调用自己,每次将返回地址推入堆栈。当这由于在下个世纪不太可能实现的基本情况而消失时,您会遇到堆栈溢出。
2021-03-24 07:47:20
非常感谢..所以有什么方法/工具可以让我用尽堆栈限制..同样,因为这是一个巨大的库文件而不是我创建的,我不完全知道在哪里事情可能会出错..
2021-03-26 07:47:20
@Oliver 如果你必须运行一个函数近 300 万亿次,你可能做错了什么。
2021-03-30 07:47:20
@Oliver - 您可能想研究动态编程 - 我的猜测是您没有那么多独特的解决方案,您正在重复步骤,因此您可能需要将其编程为多项式时间而不是二次。en.wikipedia.org/wiki/Dynamic_programming
2021-04-05 07:47:20

如果您不小心导入/嵌入同一个 JavaScript 文件两次,有时会得到这个,值得在检查器的资源选项卡中检查。

是的...我真的不知道它为什么会发生或过程是什么,尽管它也会覆盖。
2021-03-16 07:47:20
@lucygenik 下次您在批准帖子上的巨魔编辑时要更加小心。这篇文章差点被当作垃圾邮件删除(查看历史记录)
2021-03-21 07:47:20
当您不小心导入/嵌入同一个 JS 文件两次时,通常会发生此问题。导致递归循环的确切过程不是我想推测的,但是我认为这就像驾驶两辆相同的汽车以 100 英里/小时的速度通过同一个收费站。
2021-03-22 07:47:20
聚会有点晚了,但是可以想象,当代码在任何函数之外时,两者都将在两个 JS 文件中执行,并且一个可能不会相互覆盖,因为它们在任何函数之外。
2021-03-24 07:47:20
我不认为是这种情况。如果嵌入了两种相同类型的函数或变量,后者将覆盖之前的定义。
2021-04-05 07:47:20

就我而言,我发送的是输入元素而不是它们的值:

$.post( '',{ registerName: $('#registerName') } )

代替:

$.post( '',{ registerName: $('#registerName').val() } )

这将我的 Chrome 标签冻结到了一个点,它甚至没有向我显示页面无响应时的“等待/终止”对话框......

我正要添加这个作为可能的解决方案。我只是做了这件事哈哈
2021-03-11 07:47:20
谢谢你。这就是问题所在
2021-03-12 07:47:20
非常感谢,这救了我
2021-03-20 07:47:20
“我想知道为什么这种错误没有例外......”因为它是javascript。
2021-03-27 07:47:20
我想知道为什么这样的错误没有例外......谢谢!
2021-03-30 07:47:20

在您的代码中某处有一个递归循环(即最终一次又一次地调用自身直到堆栈已满的函数)。

其他浏览器要么有更大的堆栈(所以你会得到一个超时)或者他们出于某种原因吞下错误(可能是一个错误放置的 try-catch)。

发生错误时使用调试器检查调用堆栈。

我没有使用 Safari Inspector 的经验。尝试打开 JavaScript 调试器并加载您的页面。当抛出未捕获的错误时,调试器应该停止。如果这不起作用,请询问超级用户或网站管理员(请参阅页面底部)
2021-03-13 07:47:20
非常感谢您的回复。在 IE/FF 上,代码似乎运行良好。仅在桌面 Safari 和 iPad Safari 中,我收到错误消息。实际上这个 JS 文件不是我自己创建的,而是一个库文件(来自 DWR engine.js)。 directwebremoting.org 另外,当您说“调试器检查调用堆栈”时,我该如何使用 Safari Inspector 执行此操作?
2021-03-22 07:47:20
有 2 个函数命名相同的东西!!哦!
2021-03-29 07:47:20

检测 stackoverflows 的问题是有时堆栈跟踪会展开,您将无法看到实际发生的情况。

我发现 Chrome 的一些较新的调试工具对此很有用。

点击Performance tab,确保Javascript samples已启用,你会得到这样的东西。

溢出在哪里很明显!如果您单击,extendObject您将能够实际看到代码中的确切行号。

在此处输入图片说明

您还可以查看可能有用也可能没有帮助的时间安排或红鲱鱼。

在此处输入图片说明


如果您实际上无法找到问题,另一个有用的技巧是console.log在您认为问题所在的地方放置大量语句。上面的上一步可以帮助您解决这个问题。

在 Chrome 中,如果你重复输出相同的数据,它会像这样显示问题更清楚的地方。在这种情况下,堆栈在最终崩溃之前达到了 7152 帧:

在此处输入图片说明

对于任何阅读此答案的人。当然,它对我有用,我能够将其缩小为递归函数调用。我可以使用“性能”选项卡轻松地立即跟踪问题。这是由于 2 个角度元素资产被包含在一个单独的应用程序中。一旦我禁用了其中一个元素,问题就消失了。希望这对某人有帮助!
2021-03-13 07:47:20