甲骨文说在Windows上
-Xsssize默认值依赖于虚拟内存
如何在给定的Oracle JVM 8中查找java在Windows上分配的线程堆栈大小的值?
我尝试过在哪里可以找到Sun/Oracle JVM的默认XSS值?的解决方案
但它只是打印0。
java -XX:+PrintFlagsFinal -version

java -XX:+PrintFlagsFinal应该打印实际的线程堆栈大小,而不是0。对我来说好像是JVM错误。
我想优化JVM性能,并想知道为线程堆栈分配了多少内存。它是为unix平台精确指定的。奇怪的是,我无法获得Windows的这个值。
发布于 2017-07-17 10:59:08
这不是一个问题,它是一个特定于平台的行为,稍微有点向后兼容性的味道。HotSpot的源代码中有两个有趣的文件:
在globals_windows_x86中,为了使用系统默认值,HotSpot用0初始化ThreadStackSize:
// 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文档。
为什么Windows平台上的大小为零?这是将默认值传递给WinAPI的最简单的方法,并且在Java线程id=4689767中存在一个问题:
Windows:默认的线程堆栈大小是从二进制文件(java.exe)中读取的;主线程堆栈是用这个大小创建的。 隐藏主线程和其他线程之间差异的另一种解决方案是避免在主线程中运行任何java字节码,因为JNI一般认为这是不可能的。 在我们停止支持WinME 95/WinME 98/WinME之前,它不会固定在windows上
让我总结一下- ThreadStackSize是一个内部属性,可能具有任何默认值,例如,为了支持遗留平台( me /98),在Windows上使用0。PrintFlagsFinal还在没有任何保证的情况下提供调试信息,因此在没有特定知识的情况下引用这些信息是不正确的。从1.7.0_45开始,Hotpot有一个很好的内部VM特性,称为“原生内存跟踪”(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)您可以尝试将堆栈大小从缺省值(在本例中为1M )(在本例中为14个保留空间为14453 KB的线程)缩减到-Xss256k中较少的部分。
- Thread (reserved=10613KB, committed=10613KB)
(thread #14)
(stack: reserved=10552KB, committed=10552KB)
(malloc=44KB #76)
(arena=16KB #28)发布于 2018-10-18 08:10:42
我终于从JDK源代码中找到了答案。
获取源代码:
hg clone http://hg.openjdk.java.net/jdk8/jdk8/hotspot/根据JDK文档,Xss值可以更改Java线程堆栈大小。但是这个论点是如何运作的呢?以下是代码:
HANDLE thread_handle =
(HANDLE)_beginthreadex(NULL,
(unsigned)stack_size,
(unsigned (__stdcall *)(void*)) java_start,
thread,
CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
&thread_id);Xss被分配给stack_size,后者用于为线程堆栈分配内存。
但如果你什么都不做呢?在os_windows.cpp,中,请参阅以下段落:
// 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.如果不设置Xss值,则默认堆栈大小取决于PE文件(java.exe)。如果运行32位Java应用程序,默认的堆栈大小是320K。如果运行64位Java应用程序,默认的堆栈大小是1024K。
我们可以使用以下源代码来验证堆栈大小:
#include <windows.h>
typedef u_char* address;
address os::current_stack_base() {
MEMORY_BASIC_INFORMATION minfo;
address stack_bottom;
size_t stack_size;
VirtualQuery(&minfo, &minfo, sizeof(minfo));
stack_bottom = (address)minfo.AllocationBase;
stack_size = minfo.RegionSize;
// Add up the sizes of all the regions with the same
// AllocationBase.
while( 1 )
{
VirtualQuery(stack_bottom+stack_size, &minfo, sizeof(minfo));
if ( stack_bottom == (address)minfo.AllocationBase )
stack_size += minfo.RegionSize;
else
break;
}
#ifdef _M_IA64
// IA64 has memory and register stacks
//
// This is the stack layout you get on NT/IA64 if you specify 1MB stack limit
// at thread creation (1MB backing store growing upwards, 1MB memory stack
// growing downwards, 2MB summed up)
//
// ...
// ------- top of stack (high address) -----
// |
// | 1MB
// | Backing Store (Register Stack)
// |
// | / \
// | |
// | |
// | |
// ------------------------ stack base -----
// | 1MB
// | Memory Stack
// |
// | |
// | |
// | |
// | \ /
// |
// ----- bottom of stack (low address) -----
// ...
stack_size = stack_size / 2;
#endif
return stack_bottom + stack_size;
}https://stackoverflow.com/questions/45140113
复制相似问题