简体   繁体   English

使用Javascript类函数进行15次递归后的堆栈溢出

[英]Stack Overflow After 15 Recursions with Javascript Class Function

I have the following code sample to illustrate my point. 我有以下代码示例来说明我的观点。 When I load this in IE8 on Vista I get the error "Stack Overfow at line:16" 当我在Vista上的IE8中加载此文件时,出现错误“第16行的堆栈溢出”

If I recurse using a top level function (outside of the testClass object) I can recurse millions of times without a stack overflow. 如果我使用顶级函数(在testClass对象之外)递归,则可以递归数百万次而不会出现堆栈溢出。

Why is this happening? 为什么会这样呢? Ultimately I just implemented a Function Que instead of using recursion, but just doesn't make sense to me, and I'd like to understand the cause. 最终,我只是实现了一个Function Que而不是使用递归,但是对我而言这没有任何意义,我想了解原因。

-- code -- -代码-

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
<html>
    <head>
        <title>Recusion Test</title>
        <body>
        </body>

        <script type="text/javascript">

            function testClass() {
                this.x = 15;
                this.recurse = function() {
                    this.x--;
                    this.recurse();
                }
            }

            var wtf = new testClass();
                wtf.recurse();

            alert('done');
        </script>
    </head>
</html>

There is no terminating condition for your recursive statement therefore it will run forever. 您的递归语句没有终止条件,因此它将永远运行。

It appears that you want... 看来您想要...


            function testClass() {
                this.x = 15;
                this.recurse = function() {
                    if (this.x--)
                        this.recurse();
                }
            }

            var wtf = new testClass();
                wtf.recurse();

            alert('done');

Ok, here's some more insight into the issue I was having. 好的,这是我遇到的问题的更多见解。 After going back and fixing what I thought was the problem with my application I was still having the issue. 返回并修复了我认为是我的应用程序存在的问题之后,我仍然遇到了问题。 The part that made me pursue the issue was that if I recursed only 14 times it would complete successfully. 使我追究此问题的部分是,如果仅重复14次,它将成功完成。

First, I was executing the original code in an HTA and not Internet Explorer. 首先,我在HTA中而不是Internet Explorer中执行原始代码。 I'm writing a VIM based code editor similar to FCKEditor. 我正在编写类似于FCKEditor的基于VIM的代码编辑器。

Second, the structure of my code is as follows: 其次,我的代码结构如下:

-HTA -HTA

--EditorClass -编辑器类

---DivManagerClass --- DivManagerClass

----KeyBindingClass ---- KeyBindingClass

In my KeyBindingClass I had a codebase similar to the example provided (except it has a terminating condition) 在我的KeyBindingClass中,我有一个与提供的示例类似的代码库(除了具有终止条件)

In my KeyBindingClass I have a repeater property that would repeat the last keystrok N-times if a numeric modifier was pressed. 在我的KeyBindingClass中,我有一个repeater属性,如果按下了数字修饰符,它将重复最后一次击键N次。 For those that don't know pressing the keys '3' and 'x' in visual mode in vim will delete three characters. 对于那些不知道在vim可视模式下按下键“ 3”和“ x”的用户,将删除三个字符。

Everything worked fine until I used a numeric modifier greater than 14. 一切正常,直到我使用了大于14的数值修饰符。

I kept trying to reproduce this issue with a small test harness and couldn't. 我一直试图用一个小型测试工具重现此问题,但不能。 I was able to recurse up to 3000 in a basic test harness. 在基本的测试工具中,我最多可以递归3000。 So I started recreating the scenario as best I could. 所以我开始尽我所能重新创建场景。 First I moved the call to the recurse method into another class/method. 首先,我将对recurse方法的调用移到了另一个类/方法中。 That limited my call stack to somewhere around 1600 (almost half the stack just vanished.) 那限制了我的通话筹码大约为1600(几乎消失了一半)。

Then I added jQuery to the mix and moved the call to the ParentClass.recurse method into a keybinding event inside the document.onready jquery handler. 然后,我将jQuery添加到混合中,并将对ParentClass.recurse方法的调用移至document.onready jquery处理程序内的键绑定事件中。 That reduced my callstack to about 1300. 这使我的调用栈减少到大约1300。

Then I moved my code into an HTA which cut my call stack in half again! 然后,我将代码移入HTA,这又将调用堆栈减少了一半! After mimicking my codebase as best I could and as quickly as I could I reached a callstack of about 515. 在尽可能地模仿我的代码库之后,我尽可能快地达到了约515的调用栈。

After doing some reasearch I have found the IE uses available memory space to determine callstack size. 经过一些研究之后,我发现IE使用可用的内存空间来确定调用堆栈的大小。 I'm guessing the HTA is a little more strict in that regard. 我猜想HTA在这方面要严格一些。 I haven't figured out what other factor has limited my application to such a low callstack given the class structure, but it is definitely code structure that's the issue. 考虑到类结构,我还没有弄清楚还有什么其他因素将我的应用程序限制在如此低的调用栈中,但是绝对是代码结构是问题所在。

I can put my basic recursion test in a top level execution script tag and get about 1473 calls before reaching a stack overflow. 我可以将基本的递归测试放在顶级执行脚本标记中,并在达到堆栈溢出之前获得约1473个调用。

I can still use a function queue to fix my problem, but I just wanted others to know that A. I wouldn't post such a simple problem to Stack Overflow, and B. that your call stack limit can be vastly affected by the class structures surrounding functions, even though they aren't separate levels of what you'd traditionally consider a function stack. 我仍然可以使用函数队列来解决问题,但我只是想让其他人知道A。我不会将如此简单的问题发布到Stack Overflow,而B.您的调用堆栈限制可能会受到该类的极大影响。围绕函数的结构,即使它们不是传统上认为函数堆栈的单独层次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM