我有一些应用程序只能在堆栈大小增加的情况下正常运行(java选项-Xss1M),否则就是段错误。 如果我在命令行中使用-Xss1M选项,它可以工作。要将此解决方案集成到我的Jenkins作业中,我更倾向于使用_JAVA_OPTIONS环境变量方法而不是脚本修改。
令我惊讶的是,如果我说“export _JAVA_OPTIONS = -Xss1M”,它就不起作用了。我试图设置JAVA_OPTS和JAVA_TOOL_OPTIONS,使用单引号和双引号。结果总是一样的。 特别奇怪的是,Java写道“选择”了选项,尽管它没有效果:
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)
如果我使用-Xss1M作为命令行选项运行相同的命令,它可以工作:
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.
在SunOS 5.10和CentOS 4机器上,我都有相同的行为。我都使用JDK 6。 我使用https://docs.oracle.com/javase/6/docs/platform/jvmti/jvmti.html#tooloptions和https://docs.oracle.com/cd/E14592_01/doc.10142/e14608/app_orminweblogic.htm作为参考,使用Difference between _JAVA_OPTIONS JAVA_TOOL_OPTIONS and JAVA_OPTS查看_JAVA_OPTIONS用法示例。 我没有发现任何提及,好像_JAVA_OPTIONS不接受某些选项等。所以我认为它也适用于-Xss。任何人都可以指出,我的错误在哪里,请问?
UPDATE 1 :我确信命令行选项规范与_JAVA_OPTIONS实际上不是等价的东西。不仅适用于-Xss,还适用于其他选项。
我在我的Ubuntu 14.04和-XshowSettings:all选项中使用Java 7来查看如何在Java内部看到这些选项。我执行了3个命令并比较了它们的输出(差异在第一个顶行)。
$ java -XshowSettings:all -version 2>& 1 |头-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 |头-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 |头-5
VM settings:
Min. Heap Size: 2.00G
Max. Heap Size: 2.00G
Ergonomics Machine Class: server
Using VM: Java HotSpot(TM) Server VM
这意味着相同的选项-Xms,-Xmx确实具有,但只有在我们使用_JAVA_OPTIONS方法时效果有限。同样适用于-Xss:
$ _JAVA_OPTIONS =“ - Xss1m”java -XshowSettings:all -version 2>& 1 |头-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 |头-5
VM settings:
Stack Size: 1.00M
Max. Heap Size (Estimated): 910.25M
Ergonomics Machine Class: server
Using VM: Java HotSpot(TM) Server VM
不同之处在于,只有当-Xss1m是命令行选项时,它才表示“堆栈大小:1.00M”。但为什么!为什么不在_JAVA_OPTIONS ??
下提供完整的等效命令行更新2 :分别从http://hg.openjdk.java.net/jdk7/jdk7/hotspot/archive/tip.tar.gz和http://hg.openjdk.java.net/jdk7/jdk7/jdk/archive/tip.tar.gz下载了两个Java源代码“片段”(“热点”和“jdk”)。注入大量打印输出并设法从源代码构建java和所有相关库(libjvm.so,rt.jar),然后运行它。
根本原因是_JAVA_OPTIONS中的选项存储在数组_jvm_args_array中,该数组不用于在jdk-9b8c96f96a0f / src / solaris / bin / java_md.c中调用thr_create()。
有一个地方我们尝试评估堆栈大小,它是从ContinueInNewThread(...)调用JNI_GetDefaultJavaVMInitArgs(void * args_),但它只返回默认堆栈大小值,等于320K并且不要使用_JAVA_OPTIONS。解析_JAVA_OPTIONS后来发生在已经创建的线程中,看起来完全没有意义。
我已经编写了下面的调用序列来说明可能对它感兴趣的人正在发生的事情(缩进对应于调用深度)。
[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
我现在正在检查如何向OpenJDK报告错误。即使OpenJDK认为这样的实现设计得当,也应该在命令行帮助和文档中清楚地解释-Xss在_JAVA_OPTIONS中不起作用。