3

I have some application which could be run properly only with the increased stack size (java option -Xss1M), otherwise is segfaults. If I use the -Xss1M option in the command line it works. To integrate this solution to my Jenkins jobs I would prefer using a _JAVA_OPTIONS environment variable approach rather than scripts modification.

Surprisingly for me, it does not work if I say "export _JAVA_OPTIONS=-Xss1M". I tried to set also JAVA_OPTS and JAVA_TOOL_OPTIONS, used single and double quotes. The result is always the same. What is especially strange is that Java writes that "picked up" the options, although it has no effect:

build@build-solaris-01:tests> /usr/jdk/instances/jdk1.6.0/bin/java -d32 -verbose:gc -classpath ../dist/solaris/forte/prod32mt/cpjdlib.jar: -Djava.library.path=../dist/solaris/forte/prod32mt/dll intern_AFPMMD
Picked up JAVA_TOOL_OPTIONS: -Xss1M
Picked up _JAVA_OPTIONS: -Xss1M
try load: cpjdlib
Successfully loaded library: 'cpjdlib'
 License Valid? true
Segmentation Fault (core dumped)

If I run the same command using the -Xss1M as a command line option, it works:

build@build-solaris-01:tests> /usr/jdk/instances/jdk1.6.0/bin/java -Xss1M -d32 -verbose:gc -classpath ../dist/solaris/forte/prod32mt/cpjdlib.jar: -Djava.library.path=../dist/solaris/forte/prod32mt/dll intern_AFPMMD
Picked up JAVA_TOOL_OPTIONS: -Xss1M
Picked up _JAVA_OPTIONS: -Xss1M
try load: cpjdlib
Successfully loaded library: 'cpjdlib'
 License Valid? true
Success.

On both SunOS 5.10 and CentOS 4 machines I do have the same behaviour. On both I do use JDK 6. I used https://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#tooloptions and https://docs.oracle.com/cd/E14592_01/doc.10142/e14608/app_orminweblogic.htm as a reference and Difference between _JAVA_OPTIONS JAVA_TOOL_OPTIONS and JAVA_OPTS to see examples of the _JAVA_OPTIONS usage. I did not find any mentioning as if _JAVA_OPTIONS does not accept some options or the like. So I suppose it should work with -Xss as well. Could anyone point, where is my mistake, pls?

UPDATE 1: I convinced that command line option specification vs. _JAVA_OPTIONS are really NOT equivalent things. Not only for the -Xss, but for other options as well.

I used Java 7 on my Ubuntu 14.04 and the -XshowSettings:all option to see how the options are seen "inside" Java. I performed 3 commands and compared their output (the difference was in the first top lines).

$ java -XshowSettings:all -version 2>&1 | head -5

VM settings:
    Max. Heap Size (Estimated): 910.25M
    Ergonomics Machine Class: server
    Using VM: Java HotSpot(TM) Server VM

$ _JAVA_OPTIONS="-Xms2048m -Xmx2048m" java -XshowSettings:all -version 2>&1 | head -5

Picked up _JAVA_OPTIONS: -Xms2048m -Xmx2048m
VM settings:
    Max. Heap Size (Estimated): 1.92G
    Ergonomics Machine Class: server
    Using VM: Java HotSpot(TM) Server VM

$ java -Xms2048m -Xmx2048m -XshowSettings:all -version 2>&1 | head -5

VM settings:
    Min. Heap Size: 2.00G
    Max. Heap Size: 2.00G
    Ergonomics Machine Class: server
    Using VM: Java HotSpot(TM) Server VM

It means that the same options -Xms, -Xmx really have, but only a limited effect when we use the _JAVA_OPTIONS approach. And the same is valid for the -Xss:

$ _JAVA_OPTIONS="-Xss1m" java -XshowSettings:all -version 2>&1 | head -5

Picked up _JAVA_OPTIONS: -Xss1m
VM settings:
    Max. Heap Size (Estimated): 910.25M
    Ergonomics Machine Class: server
    Using VM: Java HotSpot(TM) Server VM

$ java -Xss1m -XshowSettings:all -version 2>&1 | head -5

VM settings:
    Stack Size: 1.00M
    Max. Heap Size (Estimated): 910.25M
    Ergonomics Machine Class: server
    Using VM: Java HotSpot(TM) Server VM

The difference is that it indicates "Stack Size: 1.00M" only when -Xss1m is a command line option. But why! Why not providing the complete equivalent of the command line under _JAVA_OPTIONS??

UPDATE 2: Downloaded both "pieces" of Java source code ("hotspot" and "jdk") from http://hg.openjdk.java.net/jdk7/jdk7/hotspot/archive/tip.tar.gz and http://hg.openjdk.java.net/jdk7/jdk7/jdk/archive/tip.tar.gz respectively. Injected a lot of printouts and managed to build java and all related libraries (libjvm.so, rt.jar) from source, then run it.

The root cause is that the options from _JAVA_OPTIONS are stored into the array _jvm_args_array which is not used for the call of thr_create() in the jdk-9b8c96f96a0f/src/solaris/bin/java_md.c.

There is a place where we try to evaluate the stack size, it is a call of JNI_GetDefaultJavaVMInitArgs(void *args_) from the ContinueInNewThread(...), but it just returns the default stack size value which equals 320K and does not use _JAVA_OPTIONS. Parsing of _JAVA_OPTIONS happens later in the already created thread that looks completely senseless.

I have wrote the call sequence below to illustrate what is happening for the one who is probably interested in it (indentation corresponds to the call depth).

[jdk-9b8c96f96a0f/src/share/bin/java.c]: JLI_Launch(...)
   [jdk-9b8c96f96a0f/src/share/bin/java.c]: ContinueInNewThread(InvocationFunctions* ifn, int argc, char **argv, int mode, char *what, int ret) // threadStackSize=0 (not passed via command line)
      [hotspot-9b0ca45cd756/src/share/vm/prims/jni.cpp]: JNI_GetDefaultJavaVMInitArgs(void *args_) // args->javaStackSize=320*1024 (default value is assigned), is called by pointer ifn->GetDefaultJavaVMInitArgs(&args1_1) from jdk-9b8c96f96a0f/src/share/bin/java.c
      [jdk-9b8c96f96a0f/src/solaris/bin/java_md.c]: ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) // threadStackSize=320*1024
      [jdk-9b8c96f96a0f/src/solaris/bin/java_md.c]: thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) // threadStackSize=320*1024
      [jdk-9b8c96f96a0f/src/share/bin/java.c]: JavaMain(void * args) // called with no arguments (no stack size was passed)!
         [jdk-9b8c96f96a0f/src/share/bin/java.c]: InitializeJVM(&vm, &env, &ifn)
            [hotspot-9b0ca45cd756/src/share/vm/runtime/arguments.cpp]: Arguments::parse() // is called by pointer ifn->CreateJavaVM(pvm, (void **)penv, &args) from jdk-9b8c96f96a0f/src/share/bin/java.c
               [hotspot-9b0ca45cd756/src/share/vm/runtime/arguments.cpp]: Arguments::parse_vm_init_args(args)
                  [hotspot-9b0ca45cd756/src/share/vm/runtime/arguments.cpp]: Arguments::parse_java_tool_options_environment_variable(&scp, &scp_assembly_required);
                     [hotspot-9b0ca45cd756/src/share/vm/runtime/arguments.cpp]: Arguments::parse_options_environment_variable("_JAVA_OPTIONS", scp_p, scp_assembly_required_p); // Here it writes "Picked up _JAVA_OPTIONS: -Xss1m"
                        [hotspot-9b0ca45cd756/src/share/vm/runtime/arguments.cpp]: Arguments::parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p, ENVIRON_VAR))
                           [hotspot-9b0ca45cd756/src/share/vm/runtime/arguments.cpp]: Arguments::build_jvm_args(option->optionString); // puts the option to _jvm_args_array which is accessible later as jvm_args_array() or jvm_args()
            (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); // <-Java *.class application execution

I am checking now how to report a bug to OpenJDK. Even if OpenJDK considered such an implementation properly designed, it should be clearly explained in both command line help and documentation that -Xss will not work from _JAVA_OPTIONS.

Alexander Samoylov
  • 2,358
  • 2
  • 25
  • 28
  • Did you try the following before running your first command `export _JAVA_OPTIONS='-Xss1m'` – Hackerman Mar 12 '18 at 17:58
  • Yes, of course. It makes Java to report me that it "Picked up _JAVA_OPTIONS: -Xss1m", but there is no "Stack Size: 1.00M" indicative message and no effect (since I have my application segfaulted which means that the stack size is still default). – Alexander Samoylov Mar 12 '18 at 18:01
  • Just for testing purposes...can you add this line `export _JAVA_OPTIONS='-Xss1m'` to the `~/.profile` and try again? – Hackerman Mar 12 '18 at 18:06
  • I tried it, Mr. Hackerman, but it did not work either. I opened a new shell to make it clear. The behaviour is the same. Java writes, that "Picked up _JAVA_OPTIONS: -Xss1m", but it does not give the same effect which gives the command line -Xss1m option. – Alexander Samoylov Mar 13 '18 at 10:33
  • 2
    @AlexanderSamoylov Thanks for this post! I am facing the same issue here and thanks to your precise analysis I don't have to repeat the same :-). I suppose there is still no better solution than just to add the option manually on the java command line, right? Did you report the bug? Could you please share a link to the bug report here? – Mi-La Nov 26 '20 at 14:09
  • @AlexanderSamoylov Pinging you again after comment above from Mi-La, have you succeeded opening bug? – tyger Aug 19 '21 at 17:26
  • Dear @tyger, sorry for a long delay in this story. I didn't have time for this earlier. I am going to issue a bug in a short time. I hope https://bugs.openjdk.java.net is the right place. – Alexander Samoylov Aug 30 '21 at 15:13

0 Answers0