Java堆栈溢出错误——如何在Eclipse中增加堆栈大小?

时间:2021-01-18 17:18:09

I am running a program that I've written in Java in Eclipse. The program has a very deep level of recursion for very large inputs. For smaller inputs the program runs fine however when large inputs are given, I get the following error:

我正在运行一个我在Eclipse中用Java编写的程序。该程序对非常大的输入具有非常深入的递归级别。对于较小的输入,程序运行良好,但是当给出较大的输入时,我得到如下错误:

Exception in thread "main" java.lang.*Error

Can this be solved by increasing the Java stack size and if so, how do I do this in Eclipse?

可以通过增加Java堆栈大小来解决这个问题吗?

Update:

更新:

@Jon Skeet

@Jon双向飞碟

The code is traversing a parse tree recursively in order to build up a datastructure. So, for example the code will do some work using a node in the parse tree and call itself on the node's two children, combining their results to give the overall result for the tree.

代码递归地遍历解析树以构建数据结构。因此,例如,代码将使用解析树中的一个节点做一些工作,并在节点的两个子节点上调用自己,结合它们的结果来为树提供总体结果。

The total depth of the recursion depends on the size of the parse tree but the code seems to fail (without a larger stack) when the number of recursive calls gets into the 1000s.

递归的总深度取决于解析树的大小,但当递归调用的数量达到100时,代码似乎会失败(没有更大的堆栈)。

Also I'm pretty sure the code isn't failing because of a bug as it works for small inputs.

而且我很确定代码不会因为错误而失败,因为它适用于小的输入。

7 个解决方案

#1


72  

Open the Run Configuration for your application (Run/Run Configurations..., then look for the applications entry in 'Java application').

打开应用程序的运行配置(运行/运行配置……),然后在“Java应用程序”中查找应用程序条目)。

The arguments tab has a text box Vm arguments, enter -Xss1m (or a bigger parameter for the maximum stack size). The default value is 512 kByte (SUN JDK 1.5 - don't know if it varies between vendors and versions).

arguments选项卡有一个文本框Vm参数,输入-Xss1m(或者一个更大的参数,以便最大的堆栈大小)。默认值是512 kByte (SUN JDK 1.5 -不知道它在供应商和版本之间是否有差异)。

#2


37  

It may be curable by increasing the stack size - but a better solution would be to work out how to avoid recursing so much. A recursive solution can always be converted to an iterative solution - which will make your code scale to larger inputs much more cleanly. Otherwise you'll really be guessing at how much stack to provide, which may not even be obvious from the input.

它可以通过增加堆栈大小来进行处理——但是更好的解决方案应该是找出如何避免如此多的递归。递归解决方案总是可以转换为迭代解决方案——这将使您的代码更清晰地扩展到更大的输入。否则,您将真正地猜测要提供多少堆栈,这甚至可能从输入中都不明显。

Are you absolutely sure it's failing due to the size of the input rather than a bug in the code, by the way? Just how deep is this recursion?

顺便问一下,你确定它失败是因为输入的大小而不是代码中的错误吗?这个递归有多深?

EDIT: Okay, having seen the update, I would personally try to rewrite it to avoid using recursion. Generally having a Stack<T> of "things still do to" is a good starting point to remove recursion.

编辑:好的,看到了更新,我个人会尝试重写它以避免使用递归。通常,让一个栈 的“事情仍然在做”是一个很好的开始来删除递归。

#3


10  

Add the flag -Xss1024k in the VM Arguments.

在VM参数中添加标记-Xss1024k。

You can also increase stack size in mb by using -Xss1m for example .

您还可以使用-Xss1m来增加mb的堆栈大小。

#4


5  

i also have the same problem while parsing schema definition files(XSD) using XSOM library,

在使用XSOM库解析模式定义文件时,我也遇到了同样的问题,

i was able to increase Stack memory upto 208Mb then it showed heap_out_of_memory_error for which i was able to increase only upto 320mb.

我可以将堆栈内存增加到208Mb,然后它显示heap_out_of_memory_error,我只增加到320mb。

the final configuration was -Xmx320m -Xss208m but then again it ran for some time and failed.

最后的配置是-Xmx320m -Xss208m,但是它又运行了一段时间并失败了。

My function prints recursively the entire tree of the schema definition,amazingly the output file crossed 820Mb for a definition file of 4 Mb(Aixm library) which in turn uses 50 Mb of schema definition library(ISO gml).

我的函数将递归地打印出模式定义的整个树,令人惊讶的是,输出文件超过了820Mb,以定义一个4 Mb的定义文件(Aixm库),而它又使用了50 Mb的模式定义库(ISO gml)。

with that I am convinced I have to avoid Recursion and then start iteration and some other way of representing the output, but I am having little trouble converting all that recursion to iteration.

有了这些,我确信我必须避免递归,然后开始迭代和其他表示输出的方法,但是把所有的递归转换成迭代并没有什么问题。

#5


3  

You need to have a launch configuration inside Eclipse in order to adjust the JVM parameters.

为了调整JVM参数,您需要在Eclipse中设置一个启动配置。

After running your program with either F11 or Ctrl-F11, open the launch configurations in Run -> Run Configurations... and open your program under "Java Applications". Select the Arguments pane, where you will find "VM arguments".

在使用F11或Ctrl-F11运行您的程序后,在Run ->运行配置中打开启动配置…并在“Java应用程序”下打开您的程序。选择Arguments窗格,您将在其中找到“VM参数”。

This is where -Xss1024k goes.

这是-Xss1024k。

If you want the launch configuration to be a file in your workspace (so you can right click and run it), select the Common pane, and check the Save as -> Shared File checkbox and browse to the location you want the launch file. I usually have them in a separate folder, as we check them into CVS.

如果您希望启动配置是工作区中的一个文件(以便您可以右键单击并运行它),那么选择公共窗格,并检查Save as ->共享文件复选框,并浏览到您想要启动文件的位置。我通常把它们放在一个单独的文件夹中,因为我们将它们检入CVS。

#6


2  

When the argument -Xss doesn't do the job try deleting the temporary files from:

当参数-Xss没有完成任务时,尝试从:

c:\Users\{user}\AppData\Local\Temp\.

This did the trick for me.

这对我起了作用。

#7


0  

Look at Morris in-order tree traversal which uses constant space and runs in O(n) (up to 3 times longer than your normal recursive traversal - but you save hugely on space). If the nodes are modifiable, than you could save the calculated result of the sub-tree as you backtrack to its root (by writing directly to the Node).

看一下Morris的有序树遍历,它使用常量空间并在O(n)中运行(比常规的递归遍历要长3倍),但是节省了大量的空间。如果节点是可修改的,那么当您回溯到它的根(通过直接写入节点)时,您可以保存子树的计算结果。

#1


72  

Open the Run Configuration for your application (Run/Run Configurations..., then look for the applications entry in 'Java application').

打开应用程序的运行配置(运行/运行配置……),然后在“Java应用程序”中查找应用程序条目)。

The arguments tab has a text box Vm arguments, enter -Xss1m (or a bigger parameter for the maximum stack size). The default value is 512 kByte (SUN JDK 1.5 - don't know if it varies between vendors and versions).

arguments选项卡有一个文本框Vm参数,输入-Xss1m(或者一个更大的参数,以便最大的堆栈大小)。默认值是512 kByte (SUN JDK 1.5 -不知道它在供应商和版本之间是否有差异)。

#2


37  

It may be curable by increasing the stack size - but a better solution would be to work out how to avoid recursing so much. A recursive solution can always be converted to an iterative solution - which will make your code scale to larger inputs much more cleanly. Otherwise you'll really be guessing at how much stack to provide, which may not even be obvious from the input.

它可以通过增加堆栈大小来进行处理——但是更好的解决方案应该是找出如何避免如此多的递归。递归解决方案总是可以转换为迭代解决方案——这将使您的代码更清晰地扩展到更大的输入。否则,您将真正地猜测要提供多少堆栈,这甚至可能从输入中都不明显。

Are you absolutely sure it's failing due to the size of the input rather than a bug in the code, by the way? Just how deep is this recursion?

顺便问一下,你确定它失败是因为输入的大小而不是代码中的错误吗?这个递归有多深?

EDIT: Okay, having seen the update, I would personally try to rewrite it to avoid using recursion. Generally having a Stack<T> of "things still do to" is a good starting point to remove recursion.

编辑:好的,看到了更新,我个人会尝试重写它以避免使用递归。通常,让一个栈 的“事情仍然在做”是一个很好的开始来删除递归。

#3


10  

Add the flag -Xss1024k in the VM Arguments.

在VM参数中添加标记-Xss1024k。

You can also increase stack size in mb by using -Xss1m for example .

您还可以使用-Xss1m来增加mb的堆栈大小。

#4


5  

i also have the same problem while parsing schema definition files(XSD) using XSOM library,

在使用XSOM库解析模式定义文件时,我也遇到了同样的问题,

i was able to increase Stack memory upto 208Mb then it showed heap_out_of_memory_error for which i was able to increase only upto 320mb.

我可以将堆栈内存增加到208Mb,然后它显示heap_out_of_memory_error,我只增加到320mb。

the final configuration was -Xmx320m -Xss208m but then again it ran for some time and failed.

最后的配置是-Xmx320m -Xss208m,但是它又运行了一段时间并失败了。

My function prints recursively the entire tree of the schema definition,amazingly the output file crossed 820Mb for a definition file of 4 Mb(Aixm library) which in turn uses 50 Mb of schema definition library(ISO gml).

我的函数将递归地打印出模式定义的整个树,令人惊讶的是,输出文件超过了820Mb,以定义一个4 Mb的定义文件(Aixm库),而它又使用了50 Mb的模式定义库(ISO gml)。

with that I am convinced I have to avoid Recursion and then start iteration and some other way of representing the output, but I am having little trouble converting all that recursion to iteration.

有了这些,我确信我必须避免递归,然后开始迭代和其他表示输出的方法,但是把所有的递归转换成迭代并没有什么问题。

#5


3  

You need to have a launch configuration inside Eclipse in order to adjust the JVM parameters.

为了调整JVM参数,您需要在Eclipse中设置一个启动配置。

After running your program with either F11 or Ctrl-F11, open the launch configurations in Run -> Run Configurations... and open your program under "Java Applications". Select the Arguments pane, where you will find "VM arguments".

在使用F11或Ctrl-F11运行您的程序后,在Run ->运行配置中打开启动配置…并在“Java应用程序”下打开您的程序。选择Arguments窗格,您将在其中找到“VM参数”。

This is where -Xss1024k goes.

这是-Xss1024k。

If you want the launch configuration to be a file in your workspace (so you can right click and run it), select the Common pane, and check the Save as -> Shared File checkbox and browse to the location you want the launch file. I usually have them in a separate folder, as we check them into CVS.

如果您希望启动配置是工作区中的一个文件(以便您可以右键单击并运行它),那么选择公共窗格,并检查Save as ->共享文件复选框,并浏览到您想要启动文件的位置。我通常把它们放在一个单独的文件夹中,因为我们将它们检入CVS。

#6


2  

When the argument -Xss doesn't do the job try deleting the temporary files from:

当参数-Xss没有完成任务时,尝试从:

c:\Users\{user}\AppData\Local\Temp\.

This did the trick for me.

这对我起了作用。

#7


0  

Look at Morris in-order tree traversal which uses constant space and runs in O(n) (up to 3 times longer than your normal recursive traversal - but you save hugely on space). If the nodes are modifiable, than you could save the calculated result of the sub-tree as you backtrack to its root (by writing directly to the Node).

看一下Morris的有序树遍历,它使用常量空间并在O(n)中运行(比常规的递归遍历要长3倍),但是节省了大量的空间。如果节点是可修改的,那么当您回溯到它的根(通过直接写入节点)时,您可以保存子树的计算结果。