2015-11-24 73 views
3

我試圖實現給定的初始狀態和特定目標規格在Java中的某些謎題解決獲得一臺機器上的堆棧溢出錯誤而不是其他。出於各種原因,我無法分享實際的代碼,而且這可能無關緊要。基本算法是,它使用遞歸深度優先搜索來嘗試找到一步一步的解決方案來解決這個難題。需要注意的是目標規格可能在初始狀態下無法達到。顯然,遞歸可以非常深,是疊相同的代碼

的代碼工作完美無缺的小拼圖,並適用於一些較大的上非常密集。我正在運行大量輸入的測試用例集合。在我的Macbook上,某些測試用例通過,但在另一臺計算機上,由於StackOverflowError,相同代碼中的這些相同測試用例失敗。另一臺計算機運行速度更快,因此讓我的最佳利益是讓這些測試案例像我們的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) 
+5

雙方都使用相同的Java安裝版本?例如。兩臺機器上的HotSpot 1.8.0_45?或者其中一個有OpenJDK或者有些不同? –

+0

雙方的64位操作系統? –

+0

增加了java版本。他們不同,但我很難相信後來的版本會導致「劣質」的表現。 – user1729709

回答

1

即使是同一堆棧大小堆棧的實際使用情況可能會有所不同。這可能取決於:

  • JVM廠商
  • JVM版本(甚至在次要版本的變化可能導致不同的堆棧用法)
  • 操作系統
  • 無論方法被解釋,JIT編譯的由C1或C2編譯器(C2編譯的方法通常會減少堆棧)。
  • 一些隨機的啓動條件(甚至在同一個盒子堆使用率可能會在不同的發佈不同)。

你可以檢查this answerthis answer瞭解更多詳情。建議重寫您的算法以消除堆棧壓力。例如,使用ArrayDeque來表示狀態堆棧並用循環替換遞歸。