在哪里可以找到 Oracle JVM 的默认 -Xss(堆栈大小)值?
Posted
技术标签:
【中文标题】在哪里可以找到 Oracle JVM 的默认 -Xss(堆栈大小)值?【英文标题】:Where can I find default -Xss (stack size) value for Oracle JVM? 【发布时间】:2011-08-26 14:39:25 【问题描述】:有没有人找到一个单独的 JVM 文档列出不同版本的 Oracle JVM 和不同操作系统的默认 -Xss
值?
我已经能够在jrockit docs 中找到这个表,但这对那些使用“普通”Oracle JVM 的人没有帮助。
我很欣赏 -Xss
值会因操作系统(和 JVM 版本)而异,所以也许没有一个文档列出所有最近的组合。但是,如果这里有任何读者知道任何单独的文档至少列出了 每个 JVM 版本(或至少 1.6 和 1.5)的默认 -Xss
值,或者即使仅列出 some 操作系统,那将是一个很好的开始。我对 Windows 的默认设置特别感兴趣。
我要补充一点,这是有价值的原因是我们经常看到人们建议(我认为是错误的)有人可以通过更改 -Xss
值来解决问题。但是,如果您不知道您的默认值,那么就无法知道您是通过某人推荐的任何更改来提高还是降低价值。他们通常不会指出他们所使用的版本/操作系统,所以他们的建议是否会“帮助”你是一个废话。
甚至比一些文档更好,如果有人知道查询 JVM 以获取当前值的方法,无论是从命令行还是通过 API 调用,那将更有价值。谢谢。
更新:我添加了 an answer of my own,它总结了各种建议并指向当前资源(2021 年初) 指出答案,包括我对
-Xss
值的了解 在 Windows 中。
【问题讨论】:
你读过这个oracle.com/technetwork/java/hotspotfaq-138619.html#threads_oom 谢谢,肖恩,但您确实意识到这仅适用于 1.4。注意我曾要求提供 1.5 或 1.6 的任何参考资料。事实证明,这些更难找到。抱歉,我应该表明我知道那个 1.4 技术说明,就像我引用了 jrockit 1.5 说明一样。 【参考方案1】:尝试:
java -XX:+PrintFlagsFinal -version | grep ThreadStackSize
【讨论】:
这似乎很有希望(对于 Windows 用户,您将使用 find "ThreadStackSize" 代替),但它只是将 0 报告为 ThreadStackSize 的值。我不认为这意味着大小为 0。虽然有些人可能会说这表明它使用的是“默认值”,但这只会让我们回到我的问题:a 中的默认 XSS 值到底是什么?给定JVM?我不敢相信这在 3.5 年后仍然无法回答。仍然对任何接受者开放,并感谢其他所有人迄今为止的尝试。 谢谢!这是我为 64 位 linux 得到的:java -XX:+PrintFlagsFinal -version | grep ThreadStackSize intx CompilerThreadStackSize = 0 pd product intx ThreadStackSize = 1024 pd product intx VMThreadStackSize = 1024 pd product java version "1.6.0_24" Java(TM) SE Runtime Environment (build 1.6.0_24-b07)跨度> @Rohit,大小以千字节为单位存储:bugs.openjdk.java.net/browse/JDK-8145458 晚了将近五年... 使用java -XX:+PrintFlagsFinal -version
表明 ThreadStackSize 应该是 1024k,但实际上它似乎是 64Mb,如 /proc/<pid>/maps
所示。是的,将-Xss
更改为例如 4Mb (java -Xss4m
) 并比较/proc/<pid>/maps
确认“某物”(我认为是线程堆栈分配)从 64Mb 减少到 4Mb。我使用这个小工具来显示内存段大小,gist.github.com/cosimo/e90a9f6daa1fbdc62a89843cf27f005a 最后,为了显示正在运行的进程的 JVM 标志,请改用 jcmd <pid> VM.flags
。
Cosimo,你指的是在 Windows 上,当没有指定 XSS 时?我发现 jcmd 报告 0,至少对于它报告的 VMThreadStackSize、ThreadStackSize 和 CompilerThreadStackSize,假设 XSS 将直接与其中任何一个相关。这类似于我之前报告的 printflagsfinal 在这种情况下也报告 0。很遗憾,不,如果没有设置,这些不是了解 Windows 上“当前”XSS 的方法。【参考方案2】:
此信息现在出现在 Oracle 热点常见问题解答中 http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#threads_oom
您可能会遇到线程默认堆栈大小的问题。在 Java SE 6 中,Sparc 的默认值在 32 位 VM 中为 512k,在 64 位 VM 中为 1024k。在 x86 Solaris/Linux 上,32 位 VM 为 320k,64 位 VM 为 1024k。
在 Windows 上,默认线程堆栈大小是从二进制文件 (java.exe) 中读取的。从 Java SE 6 开始,该值在 32 位 VM 中为 320k,在 64 位 VM 中为 1024k。
您可以通过运行 -Xss 选项来减小堆栈大小。例如:
java -server -Xss64k
请注意,在某些版本的 Windows 上,操作系统可能会使用非常粗略的粒度对线程堆栈大小进行四舍五入。如果请求的大小比默认大小小 1K 或更多,则堆栈大小向上舍入到默认值;否则,堆栈大小将向上取整为 1 MB 的倍数。
64k 是每个线程允许的最小堆栈空间量。
【讨论】:
谢谢,本。这是迄今为止最直接的潜在答案,但有一个小问题:该技术说明似乎指的是 Java 旧版本(“1.4”和“SE 5.0”和“SE 6”)。很可能该信息对于 Java 7 或 8 不再准确。对这些细节感兴趣的人应该注意这一点。但目前看来,在 Windows 中,唯一真正了解的方法确实是查看源代码。善良。 (至少从 Java 6 开始,他们能说出 32/64 位 Windows 的意义是什么!) 仍在寻找任何方法让 jvm 报告当前堆栈大小。不敢相信这是很难获得的,尤其是考虑到上述所有情况,甚至只是找到默认值。有些人可能会提出 jmx,但我搜索了 Java API 文档,但无济于事。有些人可能会建议使用类似 'java -XX:+PrintFlagsFinal | find "Stack"',但它只报告 JVM 启动时在 XX args 上指定的值(如果有)。它不会报告保留为默认值的值。【参考方案3】:你可以在“-XX:ThreadStackSize”选项下找到at Oracle site,与-Xss含义相同。
【讨论】:
谢谢。我确实发现其他人断言并证明 xss 和 threadstacksize 似乎是同一件事,只是在 jvm 的演变中来自不同时代的不同名称。 但至于该页面对默认值的引用,在这种情况下是相当迟钝的。是的,它在左列中列出了 -XX:ThreadStackSize=512,其标题显示该列显示“选项和默认值”,但右列显示“线程堆栈大小(以千字节为单位)。(0 表示使用默认堆栈大小) [Sparc:512;Solaris x86:320(在 5.0 及更早版本中为 256);Sparc 64 位:1024;Linux amd64:1024(在 5.0 及更早版本中为 0);所有其他为 0。]" 我感兴趣主要是 Windows,但不知道“所有其他 0”是什么意思,当第一句说“0 表示使用默认堆栈大小”时。 :-( 根据左栏和它的标题512是默认的。所以 512 适用于 Windows。 按键,不,不是这样的。 512 确实在该页面的左侧列中列为“默认值”,但该页面没有任何内容表明它显示了 Windows 的默认值。因此,threadstacksize 的框确实显示了 Windows 以外的东西。事实上,Windows 将在“所有其他”的分类中显示“0”,正如这里其他地方所讨论的,这意味着“无论操作系统默认是什么”,这再次告诉我们什么。 FWIW,那个页面(那个按键共享)确实在顶部有一个关于 Java 8 for Windows (docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html) 的文档的链接,而且那个页面至少说了这个关于 xss:“默认值取决于虚拟内存。”同样,这没有帮助,但至少是一次尝试。它确实与此处的其他讨论(其他答案和 cmets)背道而驰,其中一些人指出 Java 源代码将指示默认大小。我将提供一个指向 Java 11 资源的新答案,该资源走得更远(只是一点点)。【参考方案4】:在 2011 年首次发布这个问题的答案时,这是一次多么漫长而奇怪的旅程——从那以后的几年里得到了各种各样的答案。一些人建议使用-XX:+PrintFlagsFinal
JVM 参数,这对大多数人来说可能是最好的,但它对 Windows 没有帮助(总是报告 0)。有些人共享了各种资源(针对各种 JVM 和版本),其中一些确实试图帮助回答这个问题,但通常没有,或者没有为那些可能在 Windows 上运行 Oracle JVM 的人澄清。
这里至少更清楚一点:Java 11 是(2021 年)Oracle JVM 的当前最新 LTS(长期支持版本)版本,我找到了该当前版本的文档,其中列出了XSS(又名 ThreadStackSize)和不同操作系统的特定默认值。它位于https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE。以下是它报告的内容(以防将来链接中断):
Linux/x64(64 位):1024 KB macOS(64 位):1024 KB Oracle Solaris/x64(64 位):1024 KB Windows:默认值取决于虚拟内存
遗憾的是,Windows 用户仍然想知道:“取决于虚拟内存”是什么意思?我想这当然是指 Windows 本身的虚拟内存,但即便如此,我们如何将其转换为我们应该期望的 jvm 线程的实际堆栈大小?
回到我最初的问题:我想知道 default 是什么,因为经常有人会建议解决某些问题的方法是更改 -XSS
jvm arg(到他们会提出一些价值)。但是我们怎么知道我们是让它比默认值更大还是更小呢?根据要解决的问题,了解这一点至关重要!
10年后,我猜这是一个可能无法完成的神话任务。但是谁知道呢,也许现在或将来有人看到这个可能会带着新信息来救援。或者 Java 17(预期的下一个 LTS 版本)可能会改变一些事情。 (需要说明的是,在我写的时候,我分享的那个页面没有 Java 13 或更高版本的版本。)
如果没有别的,我把这个留给后代,至少帮助其他面临这个问题的人知道他们并不疯狂地发现很难得到一个直接的答案(尤其是关于 Windows 的默认 XSS 值,以及更改它是否会提高或降低相对于默认值的大小)。
【讨论】:
有人向我指出另一个 SO 线程,有人断言(通过对 JAva 8 的 JDK 源代码的分析)他们发现 64 位 Windows 中的默认值为 1m (1024k)。有关更多信息,请参阅:***.com/questions/45140113/…。如果我进行更多测试来确认或否认该断言(尽管有代码),我会报告,或者我很想听听其他人是否可以。但这比甲骨文的“它取决于”更好的答案,上面。 :-)【参考方案5】:IBM Java 6 用户指南 (source) 提供了默认设置:
Xss
AIX®: 256KB
IBM®I: 256KB
Linux: 256KB
Windows: 256KB
z/OS®: 256KB
【讨论】:
谢谢,chepseskaf,但我再次询问(在标题和正文中)有关 Oracle/Sun JVM 的问题。您的资源实际上来自 IBM JVM,这是不一样的。因此,虽然这些信息很有趣,但我们不能断定它也适用于 Oracle/Sun JVM。【参考方案6】:对于热点,这取决于您的架构以及其他方面。
默认堆栈大小可以在与给定平台相关的头文件的源代码中找到,例如
google code search (编辑:此服务已被停用,因为此答案已被停用,遗憾的是) 更新:这是来自 Nebelmann 的新链接:Openjdk source: globals_windows_x86.hpp
不确定这是否有帮助,但它是一个开始
【讨论】:
对于 OpenJDK 7,文件如下:hg.openjdk.java.net/jdk7/jdk7/hotspot/file/473cce303f13/src/… 有趣,格雷格和英格。我想有些人可能想探索他们的 java 源代码来找到它,但是由于许多人在没有源代码的情况下部署 JDK 或 JRE,这对他们没有帮助(除非他们再次获得它,或者找到像您共享的资源,并希望他们找到那里的特定环境。)是的,格雷格,我从一开始就承认这确实是特定于环境的。尽管如此,还是要感谢你们俩的考虑。以上是关于在哪里可以找到 Oracle JVM 的默认 -Xss(堆栈大小)值?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Actuator Controller 端点在哪里,我可以使用 jvm 调用以编程方式调用它吗?