我有一个 Java 应用程序,它使用 Xerces 解析大型 xml 模式 (.xsd),它在 Linux 和 Windows 上运行良好,但在 Solaris 上给出了 StackOverflowError,输入和配置完全相同。我知道 Xerces 使用递归来验证 xml 模式,但由于它在 Windows 和 Linux 上没有出现任何问题,我非常有信心它可以在任何地方运行。
为什么会这样?有解决方法吗?
根据此页面,默认堆栈大小取决于操作系统。
火花: 512
Solaris x86: 320(在5.0及更早版本之前为256)(更新:根据this page,主线程堆栈的大小来自ulimit。主线程堆栈被vm人为减少到-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。]
(我并不是说这个特定的参数是问题。只是强调它在不同操作系统下的差异)
这可能是因为平台之间的默认最大堆栈大小不同。
您可以使用 JVM 的 -Xss 命令行指定堆栈大小,例如
java -Xss256k
对于 256k 堆栈。这是基于每个线程分配的。
来自 javadoc 的引用:
StackOverflowError:
当由于应用程序递归太深而发生堆栈溢出时抛出。
为每个方法创建的堆栈有多大,取决于实现。这就是原因。