我只想控制 Java(groovy)应用程序中所有线程的堆栈大小。对于 Hotspot Oracle VM,我知道有两个参数可以执行此操作(
-Xss
和 XX:ThreadStackSize
)。
哪一个是首选?他们之间有什么区别吗?关于 Open JDK 7 有人在邮件列表中询问,指出
-Xss
对于 Hotpot VM 而言与 -XX:ThreadStackSize
相同。
重点是,我正在测量我的系统上可以启动多少个线程。 我的常规脚本看起来像:
int count = 0
def printCountThreads = {
println("XXX There were started $count threads.")
}
try {
while(true){
new Thread({Thread.sleep(Integer.MAX_VALUE)}).start()
count++
if(count % 1000 == 0){
printCountThreads()
}
}
} catch (Throwable e){
printCountThreads()
throw e
}
有趣的是,我只是使用 -
XX:ThreadStackSize
减少了线程数量。我正在使用环境变量 JAVA_OPTS 中的不同内容启动 groovy 应用程序。
groovy countmax-threads.groovy
当我将 JAVA_OPTS 设置为
-XX:ThreadStackSize=2m
时,我会启动大约 1000 个线程,直到内存被消耗。但是,当我使用 JAVA_OPTS='-Xss2m'
时,我会得到大约 32000 个线程,直到出现预期的错误。所以看起来-Xss
根本不起作用。
我正在使用
java版本“1.8.0_05”
Java(TM) SE 运行时环境(版本 1.8.0_05-b13)
Java HotSpot(TM) 64 位服务器 VM(内部版本 25.5-b02,混合模式)
在具有四个硬件线程和大约 8 GB RAM 的 Ubuntu 14.04 64 位计算机上。
更新:
我在我的 Windows 7 64 位机器和另一个 JDK 上重新验证了这一点:
java版本“1.8.0_20” Java(TM) SE 运行时环境(版本 1.8.0_20-b26) Java HotSpot(TM) 64 位服务器 VM(内部版本 25.20-b23,混合模式)
并且
-Xss
和-XX:ThreadStackSize
按预期工作(正如一些答案指出的那样)。所以我认为这是 Linux 特定的问题,甚至是 JDK 版本 1.8.05 中的错误。
-Xss
是 OpenJDK 和 Oracle JDK 中 -XX:ThreadStackSize
的别名。
尽管他们解析参数的方式不同:
-Xss
可以接受带 K、M 或 G 后缀的数字;-XX:ThreadStackSize=
需要一个整数(无后缀) - 堆栈大小(以千字节为单位)。
-Xss
是 Java HotSpot VM 识别的标准选项。
-XX:ThreadStackSize
,因为其他 -XX
选项不稳定,如有更改,恕不另行通知。
当前的 Oracle Java SE 8 文档表明
-Xss
和 -XX:ThreadStackSize=size
是等效的。 见-Xss
:-Xsssize
Sets the thread stack size (in bytes). Append the
letter k or K to indicate KB, m or M to indicate MB, g or G to
indicate GB. The default value depends on the platform:
Linux/ARM (32-bit): 320 KB
Linux/i386 (32-bit): 320 KB
Linux/x64 (64-bit): 1024 KB
OS X (64-bit): 1024 KB
Oracle Solaris/i386 (32-bit): 320 KB
Oracle Solaris/x64 (64-bit): 1024 KB
The following examples set the thread stack size to 1024 KB in different units:
-Xss1m
-Xss1024k
-Xss1048576
This option is equivalent to -XX:ThreadStackSize.
-XX:ThreadStackSize=size
-XX:ThreadStackSize=size
Sets the thread stack size (in bytes). Append the
letter k or K to indicate kilobytes, m or M to indicate
megabytes, g or G to indicate gigabytes. The default
value depends on the platform:
Linux/ARM (32-bit): 320 KB
Linux/i386 (32-bit): 320 KB
Linux/x64 (64-bit): 1024 KB
OS X (64-bit): 1024 KB
Oracle Solaris/i386 (32-bit): 320 KB
Oracle Solaris/x64 (64-bit): 1024 KB
The following examples show how to set the thread stack size to 1024 KB in different units:
-XX:ThreadStackSize=1m
-XX:ThreadStackSize=1024k
-XX:ThreadStackSize=1048576
This option is equivalent to -Xss.
Oracle Java SE 8 文档建议 -Xss 和 -XX:ThreadStackSize=size 是等效的。 但这是不正确的。尝试例如。
java -XX:ThreadStackSize=1024 -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
java -Xss1024 -version
The stack size specified is too small, Specify at least 160k
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
这是固定的,例如在 Java 14 文档:
-XX:ThreadStackSize=大小 设置 Java 线程堆栈大小(以千字节为单位)。使用缩放后缀(例如 k)会导致缩放 千字节值,以便 -XX:ThreadStackSize=1k 设置 Java 线程堆栈大小为 1024*1024 字节或 1 兆字节。
和
-Xss 尺寸 设置线程堆栈大小(以字节为单位)。
-Xss
仅适用于 main
Java 线程,但 -XX:ThreadStackSize
适用于所有 Java 线程。
如果在命令行上传递了-Xss(或-ss), 它被启动器直接拾取并稍后用于创建 “主”Java 线程,无需向 VM 询问首选线程堆栈 尺寸。不一致的根源在于: 如果 -Xss 在 -XX:ThreadStackSize 之后给出,那么事情仍然很好; 否则,“主”Java 线程将具有由 -Xss 指定的堆栈大小 其他 Java 线程的堆栈大小仍将遵循 线程堆栈大小。
-Xss 和 -XX:ThreadStackTrace 在影响线程最大堆栈大小的相同 JVM 属性方面是相似的。 差异在于测量单位。
-Xss 以 bytes 为单位设置最大线程堆栈大小,并且接受后缀。例如,-Xss1m 会将限制设置为 1048576 字节
java -XX:+PrintFlagsFinal -Xss1m 2> /dev/null | grep "intx ThreadStackSize"
intx ThreadStackSize := 1024 {pd product}
值以千字节为单位
-XX:ThreadStackSize 设置最大线程堆栈大小(以 kilobytes 为单位)。因此,该值乘以 1024。要设置与上面示例相同的值,您需要输入 1024 或 1k
java -XX:+PrintFlagsFinal -XX:ThreadStackSize=1024 2> /dev/null | grep "intx ThreadStackSize"
intx ThreadStackSize := 1024 {pd product}
java -XX:+PrintFlagsFinal -XX:ThreadStackSize=1k 2> /dev/null | grep "intx ThreadStackSize"
intx ThreadStackSize := 1024 {pd product}