java - Windows 上 JDK 8 的默认 -Xss 值

标签 java jvm jvm-hotspot

甲骨文 says that on Windows

-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

enter image description here

java -XX:+PrintFlagsFinal 应该打印实际的线程堆栈大小,而不是 0。对我来说看起来像 JVM 错误。

我想调整 JVM 性能并想知道为线程堆栈分配了多少内存。它是为 unix platforms 精确指定的.奇怪的是我无法为 Windows 获取此值。

最佳答案

这不是问题,它是一个平台特定的行为,带有轻微的向后兼容性。 HotSpot 的源代码中有两个有趣的文件:

  1. globals_windows_x86.hpp为运行时系统使用的 Windows 平台相关标志设置默认值。
  2. 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/

相关文章:

java - 制作一个二维的 10x2 数组,每个元素设置为字符串 "x"

java - Java 中的 Base64 编码与 C# 中的 HttpServerUtility.UrlTokenEncode

java - ClassCastException : java. math.BigInteger 在连接到 MySQL 时无法转换为 java.lang.Long

Java:如何跟踪/监视 CMS 垃圾收集器的 GC 时间?

java - JIT 未优化涉及 Integer.MAX_VALUE 的循环

java - JRHtmlExporter 现已弃用。如何定义图片保存路径?

java - -Xss JVM 选项的实际作用是什么

reflection - 从 KType 创建类实例的正确方法是什么

java - 在 Linux 上的 java hotspot jvm 中使用大页面和 DirectByteBuffer

java - 我如何确定 Hotspot JVM 决定重新编译 JIT :ed code a second time? 的原因