LinuxとWindowsでは正常に動作するXercesを使用して大きなxmlスキーマ(.xsd)を解析するJavaアプリケーションがありますが、Solarisではまったく同じ入力と構成でStackOverflowErrorが発生します。Xercesが再帰を使用してxmlスキーマを検証することは知っていますが、WindowsとLinuxで問題が発生しなかったため、どこでも実行できると確信していました。
なぜこれが起こるのですか?回避策はありますか?
このページによると、デフォルトのスタックサイズはOSによって異なります。
Sparc: 512
Solaris x86: 320(5.0以前では256以前でした) (更新:このページによると、メインスレッドスタックのサイズはulimitから取得されます。メインスレッドスタックは、仮想マシンによって人為的に-Xss値に縮小されます)
Sparc 64ビット: 1024
Linux amd64: 1024(5.0以前では0でした)(更新:デフォルトのサイズはulimitから取得されますが、-Xssで縮小できます)
Windows: 256(こちらも)
-Xssフラグを使用してデフォルト設定を変更できます。例えば:
java ... -Xss1024k ... <classname>
デフォルトのスタックサイズを1Mbに設定します。
Hotspot VMパラメータのデフォルトは、アーキテクチャによって異なる場合があることに注意してください。Windows / Linuxでのデフォルトを決定し、Solaris用に設定してみます。
例えば:
-XX:ThreadStackSize = 512-スレッドスタックサイズ(キロバイト単位)。(0はデフォルトのスタックサイズを使用することを意味します)[Sparc:512; Solaris x86:320(5.0以前では256以前)。Sparc 64ビット:1024; Linux amd64:1024(5.0以前では0でした); 他のすべて0。]
(この特定のパラメーターが問題であることを示唆しているわけではありません。異なるOSでの違いを強調するだけです)
これは、デフォルトの最大スタックサイズがプラットフォーム間で異なるためと考えられます。
JVMへの-Xssコマンドラインを使用してスタックサイズを指定できます。例:
java -Xss256k
256kスタックの場合。これは、スレッドごとに割り当てられます。
javadocからの引用:
StackOverflowError:
アプリケーションの繰り返しが深すぎるためにスタックオーバーフローが発生した場合にスローされます。
メソッドごとに作成されるスタックの大きさは、実装に依存します。それが理由。