超出最大调用堆栈大小错误
我正在使用 Direct Web Remoting (DWR) JavaScript 库文件,并且仅在 Safari(桌面版和 iPad)中收到
错误
超出了最大调用堆栈大小。
这个错误到底是什么意思?它是否完全停止处理?
还有针对 Safari
浏览器的任何修复(实际上是在 iPad Safari
上,它说
JS:执行超时
,我假设是相同的调用堆栈问题)
I am using a Direct Web Remoting (DWR) JavaScript library file and am getting an error only in Safari (desktop and iPad)
It says
Maximum call stack size exceeded.
What exactly does this error mean and does it stop processing completely?
Also any fix for Safari
browser (Actually on the iPad Safari
, it says
JS:execution exceeded timeout
which I am assuming is the same call stack issue)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
这意味着在代码中的某个地方,您正在调用一个函数,该函数又调用另一个函数,依此类推,直到达到调用堆栈限制。
这几乎总是因为递归函数的基本情况未得到满足。
查看堆栈
考虑这段代码...
这是几次调用后的堆栈...
尽你所能看,调用堆栈会不断增长,直到达到极限:浏览器硬编码的堆栈大小或内存耗尽。
为了修复它,请确保您的递归函数具有能够满足的基本情况......
It means that somewhere in your code, you are calling a function which in turn calls another function and so forth, until you hit the call stack limit.
This is almost always because of a recursive function with a base case that isn't being met.
Viewing the stack
Consider this code...
Here is the stack after a handful of calls...
As you can see, the call stack grows until it hits a limit: the browser hardcoded stack size or memory exhaustion.
In order to fix it, ensure that your recursive function has a base case which is able to be met...
就我而言,我发送的是输入元素而不是它们的值:
而不是:
这将我的 Chrome 选项卡冻结到了一个点,当页面变得无响应时,它甚至没有向我显示“等待/终止”对话框...
In my case, I was sending input elements instead of their values:
Instead of:
This froze my Chrome tab to a point it didn't even show me the 'Wait/Kill' dialog for when the page became unresponsive...
如果您不小心导入/嵌入同一个 JavaScript 文件两次,有时可能会出现这种情况,值得在检查器的资源选项卡中检查。
You can sometimes get this if you accidentally import/embed the same JavaScript file twice, worth checking in your resources tab of the inspector.
代码中的某处存在递归循环(即最终一次又一次调用自身直到堆栈已满的函数)。
其他浏览器要么有更大的堆栈(所以你会得到一个超时),要么因为某种原因吞掉错误(可能是放置不当的 try-catch)。
当错误发生时,使用调试器检查调用堆栈。
There is a recursive loop somewhere in your code (i.e. a function that eventually calls itself again and again until the stack is full).
Other browsers either have bigger stacks (so you get a timeout instead) or they swallow the error for some reason (maybe a badly placed try-catch).
Use the debugger to check the call stack when the error happens.
检测堆栈溢出的问题是有时堆栈跟踪会展开,您将无法看到实际发生的情况。
我发现 Chrome 的一些较新的调试工具对此很有用。
点击
性能选项卡
,确保启用Javascript示例
,您将得到类似这样的结果。溢出的位置非常明显!如果您单击
extendObject
,您将能够实际看到代码中的确切行号。您还可以查看可能有帮助或没有帮助的时间安排或转移注意力的时间。
如果您实际上无法找到问题,另一个有用的技巧是在您认为问题所在的位置放置大量
console.log
语句 上面的上一步可以帮助您解决此问题。在 Chrome 中,如果您重复输出相同的数据,它会像这样显示,更清楚地显示问题所在。在本例中,堆栈在最终崩溃之前达到了 7152 帧:
The problem with detecting stackoverflows is sometimes the stack trace will unwind and you won't be able to see what's actually going on.
I've found some of Chrome's newer debugging tools useful for this.
Hit the
Performance tab
, make sureJavascript samples
are enabled and you'll get something like this.It's pretty obvious where the overflow is here! If you click on
extendObject
you'll be able to actually see the exact line number in the code.You can also see timings which may or may not be helpful or a red herring.
Another useful trick if you can't actually find the problem is to put lots of
console.log
statements where you think the problem is. The previous step above can help you with this.In Chrome if you repeatedly output identical data it will display it like this showing where the problem is more clearly. In this instance the stack hit 7152 frames before it finally crashed:
就我而言,我使用以下命令将大字节数组转换为字符串:
bytes
包含数百万个条目,该条目太大而无法放入堆栈。In my case, I was converting a large byte array into a string using the following:
bytes
contained several million entries, which is too big to fit on the stack.这也可能导致
超出最大调用堆栈大小
错误:此处相同:
来自 Mozilla 文档:
所以尝试:
This can also cause a
Maximum call stack size exceeded
error:Same here:
From the Mozilla Docs:
So try:
就我而言,单击事件在子元素上传播。所以,我必须输入以下内容:
:
这是 html 代码:
In my case, click event was propagating on child element. So, I had to put the following:
on click event:
Here is the html code:
就我而言,我有两个同名的变量!
In my case, it was that I have 2 variables with the same name!
检查 Chrome 开发工具栏控制台中的错误详细信息,这将为您提供调用堆栈中的函数,并指导您找到导致错误的递归。
Check the error details in the Chrome dev toolbar console, this will give you the functions in the call stack, and guide you towards the recursion that's causing the error.
就我而言,我基本上忘记获取
input
的value
。错误
正确
In my case, I basically forget to get the
value
ofinput
.Wrong
Correct
发送输入元素而不是它们的值很可能会像 FK 提到的那样解决它
Sending input elements instead of their values will most likely resolve it like FK mentioned
如果您出于某种原因需要运行无限进程/递归,您可以在单独的线程中使用 webworker。
http://www.html5rocks.com/en/tutorials/workers/basics/< /a>
如果你想操作 dom 元素并重绘,请使用动画
http://creativejs.com/resources/requestanimationframe/
If you need a infinite process/recursion running for some reason, you can use a webworker in a seperate thread.
http://www.html5rocks.com/en/tutorials/workers/basics/
if you want to manipulate dom elements and redraw, use animation
http://creativejs.com/resources/requestanimationframe/
这里几乎每个答案都表明这只能由无限循环引起。这不是真的,否则您可能会通过深度嵌套调用来过度运行堆栈(并不是说这是有效的,但它肯定在可能的范围内)。如果您可以控制 JavaScript VM,则可以调整堆栈大小。例如:
node --stack-size=2000 另
请参阅:如何增加 Node.js 中的最大调用堆栈大小
Nearly every answer here states that this can only be caused by an infinite loop. That's not true, you could otherwise over-run the stack through deeply nested calls (not to say that's efficient, but it's certainly in the realm of possible). If you have control of your JavaScript VM, you can adjust the stack size. For example:
node --stack-size=2000
See also: How can I increase the maximum call stack size in Node.js
我们最近在我们正在开发的管理网站中添加了一个字段 - contact_type...很简单吧?好吧,如果你调用 select“type”并尝试通过 jquery ajax 调用发送它,它会失败,并在 jquery.js 中深深埋藏这个错误 不要这样做:
问题是 type:type - 我相信是我们将参数命名为“type”——有一个名为 type 的值变量不是问题。我们将其更改为:
并相应地重写了 some_function.php - 问题解决了。
We recently added a field to an admin site we are working on - contact_type... easy right? Well, if you call the select "type" and try to send that through a jquery ajax call it fails with this error buried deep in jquery.js Don't do this:
The problem is that type:type - I believe it is us naming the argument "type" - having a value variable named type isn't the problem. We changed this to:
And rewrote some_function.php accordingly - problem solved.
就我而言,两个 jQuery 模式显示堆叠在一起。防止这种情况解决了我的问题。
In my case, two jQuery modals were showing stacked on top of each other. Preventing that solved my problem.
检查您是否有一个调用自身的函数。例如
Check if you have a function that calls itself. For example
对于我这个 TypeScript 初学者来说,这是 _var1 的 getter 和 setter 的问题。
For me as a beginner in TypeScript, it was a problem in the getter and the setter of _var1.
在上面的
data
函数中,我使用了相同的名称d.loanRef = LoanRef
但没有创建变量loanRef
因此递归声明了自身。解决方案:声明一个
loanRef
变量,或者更好的是,使用与d.loanRef
上使用的名称不同的名称。In the
data
function above, I used the same named.loanRef = loanRef
but had not created a variableloanRef
therefore recursively declaring itself.Solution: Declare a
loanRef
variable or better still, use a different name from the one used ond.loanRef
.该问题可能是由于递归调用没有任何终止条件所致。
就像我的例子一样,如果您看到下面的代码,我的 API 调用方法和我用于在该 API 调用后执行操作的方法具有相同的名称。
因此,基本上,解决方案是删除此递归调用。
The issue might be because of recursive calls without any base condition for it to terminate.
Like in my case, if you see the below code, I had the same name for the API call method and the method which I used to perform operations post that API call.
So, basically, the solution is to remove this recursive call.
如果减少 1,则下面相同代码的两次调用都可以在我的计算机上的 Chrome 32 中运行,例如 17905 与 17904。如果按原样运行,它们将产生错误“RangeError:超出最大调用堆栈大小”。看来这个限制不是硬编码的,而是取决于您机器的硬件。确实,如果作为函数调用,则该自我施加的限制会高于作为方法调用的情况,即,当作为函数调用时,该特定代码使用更少的内存。
作为方法调用:
作为函数调用:
Both invocations of the identical code below if decreased by 1 work in Chrome 32 on my computer e.g. 17905 vs 17904. If run as is they will produce the error "RangeError: Maximum call stack size exceeded". It appears to be this limit is not hardcoded but dependant on the hardware of your machine. It does appear that if invoked as a function this self-imposed limit is higher than if invoked as a method i.e. this particular code uses less memory when invoked as a function.
Invoked as a method:
Invoked as a function:
我也遇到了类似的问题,这里是详细信息
上传徽标时,
使用下拉徽标上传框CSS.css
在更正之前
我的代码是:控制台中的错误:
我通过删除
onclick="$('#filePhoto').click 解决了这个问题()"
来自 div 标签。I also faced similar issue here is the details
when uploading logo using dropdown logo upload box
CSS.css
before correction my code was :
The error in console:
I solved it by removing
onclick="$('#filePhoto').click()"
from div tag.我遇到了同样的问题
我已经通过删除在 ajax 上使用了两次的字段名称解决了这个问题
例如
I was facing same issue
I have resolved it by removing a field name which was used twice on ajax
e.g
我的情况的问题是因为我的子路由与父路由具有相同的路径:
所以我必须删除子路由的行
The issue in my case is because I have children route with same path with the parent :
So I had to remove the line of the children route
当 MongoDB 数据库的架构与我们创建的模型不匹配时,我在express/nodejs 应用程序中遇到此错误。
I got this error in express/nodejs app, when the schema of MongoDB database and the models which we have created don't match.
你可以在crome浏览器中找到你的递归函数,按ctrl+shift+j然后按source选项卡,这给你代码编译流程,你可以在代码中找到使用断点。
you can find your recursive function in crome browser,press ctrl+shift+j and then source tab, which gives you code compilation flow and you can find using break point in code.
我知道这个线程很旧,但我认为值得一提的是我发现这个问题的场景,这样它可以帮助其他人。
假设您有这样的嵌套元素:
您无法在其父元素的事件内操作子元素事件,因为它会传播到自身,进行递归调用,直到引发异常。
因此,此代码将失败:
您有两种选择来避免这种情况:
I know this thread is old, but i think it's worth mentioning the scenario i found this problem so it can help others.
Suppose you have nested elements like this:
You cannot manipulate the child element events inside the event of its parent because it propagates to itself, making recursive calls until the exception is throwed.
So this code will fail:
You have two options to avoid this:
我遇到这个错误是因为我有两个同名的 JS 函数
I had this error because I had two JS Functions with the same name
如果您正在使用谷歌地图,请检查传入
new google.maps.LatLng
的 lat lng 的格式是否正确。就我而言,它们被视为未定义。If you are working with google maps, then check if the lat lng are being passed into
new google.maps.LatLng
are of a proper format. In my case they were being passed as undefined.有时会因为转换数据类型而发生,例如您有一个被视为字符串的对象。
以nodejs或js客户端为例,socket.id不是字符串。要将其用作字符串,您必须在前面添加单词 String:
Sometimes happened because of convert data type , for example you have an object that you considered as string.
socket.id in nodejs either in js client as example, is not a string. to use it as string you have to add the word String before: