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.