【发布时间】:2009-05-20 13:35:19
【问题描述】:
我有一个 Java 应用程序,它使用 Xerces 解析大型 xml 模式 (.xsd),它在 Linux 和 Windows 上运行良好,但在 Solaris 上给出了 StackOverflowError,输入和配置完全相同。我知道 Xerces 使用递归来验证 xml 模式,但由于它在 Windows 和 Linux 上没有出现任何问题,我非常有信心它可以在任何地方运行。
为什么会这样?有解决办法吗?
【问题讨论】:
我有一个 Java 应用程序,它使用 Xerces 解析大型 xml 模式 (.xsd),它在 Linux 和 Windows 上运行良好,但在 Solaris 上给出了 StackOverflowError,输入和配置完全相同。我知道 Xerces 使用递归来验证 xml 模式,但由于它在 Windows 和 Linux 上没有出现任何问题,我非常有信心它可以在任何地方运行。
为什么会这样?有解决办法吗?
【问题讨论】:
根据this page,默认堆栈大小取决于操作系统。
Sparc: 512
Solaris x86: 320(在 5.0 及更早版本之前为 256)(更新:根据this page,主线程堆栈的大小来自 ulimit。主线程stack被vm人为地减少到-Xss值)
Sparc 64 位: 1024
Linux amd64: 1024(在 5.0 及更早版本中为 0)(更新:默认大小来自 ulimit,但我可以用 -Xss 减小)
Windows: 256(也是here)
您可以使用 -Xss 标志更改默认设置。例如:
java ... -Xss1024k ... <classname>
将默认堆栈大小设置为 1Mb。
【讨论】:
请注意,不同架构的 Hotspot VM 参数默认为 may be different。我会确定 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。]
(我并不是说这个特定的参数是问题所在。只是强调它在不同操作系统下的差异)
【讨论】:
这可能是因为平台之间的默认最大堆栈大小不同。
您可以使用 -Xss 命令行指定堆栈大小到 JVM,例如
java -Xss256k
对于 256k 堆栈。这是按线程分配的。
【讨论】:
引用自 javadoc:
StackOverflowError:
由于应用程序递归太深而发生堆栈溢出时引发。
为每个方法创建的堆栈有多大,取决于实现。就是这个原因。
【讨论】: