在一台机器上出现堆栈溢出错误,但在同一代码上另一台机器却没有

Getting stack overflow error on one machine but not the other on the same code

我正在尝试在给定初始状态和特定目标规范的情况下,在 Java 中实施特定的解谜器。由于各种原因,我无法共享实际代码,而且这可能无关紧要。基本算法是它使用递归深度优先搜索来尝试找到解决难题的逐步解决方案。需要注意的是,目标规范可能无法从初始状态达到。显然递归可以很深并且在堆栈上非常密集

该代码可以完美地处理小谜题,也可以处理一些较大的谜题。我正在 运行 收集大量输入的测试用例。在我的 Macbook 上,某些测试用例通过了,但在另一台计算机上,这些相同的测试用例在相同的代码上由于 WhosebugError 而失败。另一台计算机 运行s 更快,所以让这些测试用例像在我的 Macbook 上一样工作符合我的最大利益。您可以安全地排除无限递归导致堆栈溢出错误的可能性——我知道这是因为堆栈 运行 正在退出。

我运行以下命令:

在我的 macbook 上:

$ java -XX:+PrintFlagsFinal -version | grep -iE 'heapsize|permsize|threadstacksize'
uintx AdaptivePermSizeWeight                    = 20              {product}           
 intx CompilerThreadStackSize                   = 0               {pd product}        
uintx ErgoHeapSizeLimit                         = 0               {product}           
uintx InitialHeapSize                           = 0               {product}           
uintx LargePageHeapSizeThreshold                = 134217728       {product}           
uintx MaxHeapSize                               = 132120576       {product}           
uintx MaxPermSize                               = 85983232        {pd product}        
uintx PermSize                                  = 21757952        {pd product}        
 intx ThreadStackSize                           = 1024            {pd product}        
 intx VMThreadStackSize                         = 1024            {pd product}   

在另一台计算机上(使用 Ubuntu)我 运行:

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'
 intx CompilerThreadStackSize                   = 0               {pd product}        
uintx ErgoHeapSizeLimit                         = 0               {product} 
uintx HeapSizePerGCThread                       = 87241520        {product}           
uintx InitialHeapSize                          := 526385152       {product}           
uintx LargePageHeapSizeThreshold                = 134217728       {product}           
uintx MaxHeapSize                              := 8420065280      {product}           
 intx ThreadStackSize                           = 1024            {pd product}        
 intx VMThreadStackSize                         = 1024            {pd product}   

那么,这里出了什么问题?为什么我的 macbook 运行 测试没有发生意外,而另一台机器堆栈溢出?

我不确定哪些附加信息对此处有帮助,但如果需要我可以提供。

编辑:java -version 两者:

在 Macbook 上:

java version "1.6.0_32"
Java(TM) SE Runtime Environment (build 1.6.0_32-b05-420)
Java HotSpot(TM) 64-Bit Server VM (build 20.7-b02-420, mixed mode)

在 Ubuntu:

java version “1.8.0_45”
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

即使堆栈大小相同,堆栈的实际使用也可能不同。它可能取决于:

  • JVM 供应商
  • JVM 版本(即使更改次要版本也可能导致不同的堆栈使用)
  • 操作系统
  • 方法是否被解释,通过C1或C2编译器进行JIT编译(C2编译的方法通常吃栈少)。
  • 一些随机的启动条件(即使在同一个盒子上,堆栈使用在不同的启动时也可能不同)。

您可以查看this answer and this answer了解更多详情。建议重写您的算法以消除堆栈压力。例如,用ArrayDeque表示状态栈,用循环代替递归。