Default -Xss value on Windows for JDK 8

Viewed 12861

Oracle says that on Windows

-Xsssize The default value depends on virtual memory

How i can find out the value of the thread stack size that java allocate on Windows in a given Oracle JVM 8?

I've tried the solution from where to find default XSS value for Sun/Oracle JVM?

But it simply prints 0.

java -XX:+PrintFlagsFinal -version

enter image description here

java -XX:+PrintFlagsFinal should print actual thread stack size, not 0. Looks like JVM bug for me.

I want to tune JVM perfomance and want to know how many memory is allocated for the threads' stack. It is specified precisely for unix platforms. And it's weird that i can not get this value for Windows.

2 Answers

I finally found the answer from the JDK source code.

Get the source code:

hg clone http://hg.openjdk.java.net/jdk8/jdk8/hotspot/

According to the JDK documentation, Xss value can change the Java Thread Stack Size. But how does the argument work? Here is the code :

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 is assigned to stack_size, which is used to allocate memory for the thread stack.

But what if you set nothing? In os_windows.cpp, see the following paragraph:

// 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.

If you do not set Xss value, the default stack size depends on the PE file(java.exe). If you run a 32-bit Java app, the default stack size is 320K. If you run a 64-bit Java app, the default stack size is 1024K.

We can use following source code to verify the stack size:

    #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;
    }
Related