-Xsssize The default value depends on virtual memory
在给定的 Oracle JVM 8 中,我如何找出 java 在 Windows 上分配的线程堆栈大小的值?
我已经尝试了来自 where to find default XSS value for Sun/Oracle JVM? 的解决方案
但它只是打印 0。
java -XX:+PrintFlagsFinal -version
java -XX:+PrintFlagsFinal
应该打印实际的线程堆栈大小,而不是 0。对我来说看起来像 JVM 错误。
我想调整 JVM 性能并想知道为线程堆栈分配了多少内存。它是为 unix platforms 精确指定的.奇怪的是我无法为 Windows 获取此值。
最佳答案
这不是问题,它是一个平台特定的行为,带有轻微的向后兼容性。 HotSpot 的源代码中有两个有趣的文件:
- globals_windows_x86.hpp为运行时系统使用的 Windows 平台相关标志设置默认值。
- os_windows_x86.cpp - 创建具有指定堆栈大小的线程
在 globals_windows_x86 中,HotSpot 将 ThreadStackSize 初始化为 0 以使用系统默认值:
// Default stack size on Windows is determined by the executable (java.exe
// has a default value of 320K/1MB [32bit/64bit]). Depending on Windows version, changing
// ThreadStackSize to non-zero may have significant impact on memory usage.
// See comments in os_windows.cpp.
define_pd_global(intx, ThreadStackSize, 0); // 0 => use system default
define_pd_global(intx, VMThreadStackSize, 0); // 0 => use system default
在 os_windows_x86 中有解释为什么堆栈大小在 Windows 平台上为 0:
// Create the Win32 thread
//
// Contrary to what MSDN document says, "stack_size" in _beginthreadex()
// does not specify stack size. Instead, it specifies the size of
// initially committed space. The stack size is determined by
// PE header in the executable. If the committed "stack_size" is larger
// than default value in the PE header, the stack is rounded up to the
// nearest multiple of 1MB. For example if the launcher has default
// stack size of 320k, specifying any size less than 320k does not
// affect the actual stack size at all, it only affects the initial
// commitment. On the other hand, specifying 'stack_size' larger than
// default value may cause significant increase in memory usage, because
// not only the stack space will be rounded up to MB, but also the
// entire space is committed upfront.
//
// Finally Windows XP added a new flag 'STACK_SIZE_PARAM_IS_A_RESERVATION'
// for CreateThread() that can treat 'stack_size' as stack size. However we
// are not supposed to call CreateThread() directly according to MSDN
// document because JVM uses C runtime library. The good news is that the
// flag appears to work with _beginthredex() as well.
您还可以阅读 MSDN document .
为什么在 Windows 平台上 size 为零?这是将默认值传递给 WinAPI 的最简单方法,Java 主线程中存在问题 http://bugs.java.com/view_bug.do?bug_id=4689767有决心:
Windows: the default thread stack size is read from the binary (java.exe); the main thread stack is created with this size.
An alternative solution that hides the differences between the main thread and other threads is to avoid running any java bytecodes in the main thread believe it is not possible in general because of JNI.
It will NOT be fixed on windows till we stop supporting supporting Win95/Win98/WinME
让我总结一下 - ThreadStackSize
是一个内部属性,可以有任何默认值,例如在 Windows 上为 0 以支持旧版平台 (ME/98)。 PrintFlagsFinal
还提供调试信息,但不提供任何保证,因此在没有特定知识的情况下引用此信息是不正确的。从 1.7.0_45 开始,Hotpot 有一个很好的内部 VM 功能,称为 "Native Memory Tracking" (NMT)
java -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics -version
...
- Thread (reserved=14453KB, committed=14453KB)
(thread #14)
(stack: reserved=14392KB, committed=14392KB)
(malloc=44KB #76)
(arena=16KB #28)
您可以尝试使用 -Xss256k
将堆栈大小从默认值(在本例中为 1M,14 个线程,保留空间 14453 KB)缩减到更少:
- Thread (reserved=10613KB, committed=10613KB)
(thread #14)
(stack: reserved=10552KB, committed=10552KB)
(malloc=44KB #76)
(arena=16KB #28)
关于java - Windows 上 JDK 8 的默认 -Xss 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45140113/