Невозможно установить -Xss с помощью _JAVA_OPTIONS

У меня есть приложение, которое может работать правильно только с увеличенным размером стека (опция java -Xss1M), в противном случае это segfaults. Если я использую опцию -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 и https://docs.oracle.com/cd/E14592_01/doc.10142/e14608/app_orminweblogic.htm в качестве ссылки и разницы между _JAVA_OPTIONS JAVA_TOOL_OPTIONS и JAVA_OPTS, чтобы увидеть примеры использования _JAVA_OPTIONS. Я не нашел упоминаний о том, что _JAVA_OPTIONS не принимает некоторые параметры или тому подобное. Так что я полагаю, что это должно работать и с -Xss. Может ли кто-нибудь указать, где моя ошибка, пожалуйста?

ОБНОВЛЕНИЕ 1: Я убежден, что спецификация параметра командной строки и _JAVA_OPTIONS действительно НЕ эквивалентны. Не только для -Xss, но и для других опций.

Я использовал Java 7 в своей Ubuntu 14.04 и опцию -XshowSettings: все, чтобы увидеть, как эти опции видны "внутри" 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

Разница в том, что он показывает "Размер стека: 1,00M" только тогда, когда -Xss1m является параметром командной строки. Но почему! Почему бы не предоставить полный эквивалент командной строки в _JAVA_OPTIONS??

ОБНОВЛЕНИЕ 2: Загружены обе "части" исходного кода Java ("горячая точка" и "jdk") с 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 и все связанные библиотеки (libjvm.so, rt.jar) из исходного кода, а затем запустить его.

Основная причина заключается в том, что параметры из _JAVA_OPTIONS хранятся в массиве _jvm_args_array, который не используется для вызова thr_create() в jdk-9b8c96f96a0f/src/solaris/bin/java_md.c.

Есть место, где мы пытаемся оценить размер стека, это вызов JNI_GetDefaultJavaVMInitArgs(void *args_) из ContinueInNewThread(...), но он просто возвращает значение размера стека по умолчанию, равное 320 КБ, и не использует _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.

0 ответов

Другие вопросы по тегам