Как использовать posix_spawn() в Java

#java #solaris

#java #solaris

Вопрос:

Я унаследовал устаревшее приложение, которое использует ProcessBuilder.start() для выполнения скрипта на сервере Solaris 10.

К сожалению, этот вызов скрипта завершается с ошибкой из-за проблемы с памятью, как описано здесь

Рекомендация Oracle заключается в использовании, posix_spawn() поскольку под прикрытием ProcessBuilder.start() используется fork/exec .

Я не смог найти никаких примеров (например, как вызвать "myScript.sh" )

использование posix_spawn() в Java или даже какие пакеты требуются.

Не могли бы вы, пожалуйста, указать мне на простой пример того, как использовать posix_spawn() в Java?

Комментарии:

1. я этого не пробовал, но эта библиотека-оболочка сервиса, похоже, обеспечивает замену Runtime.exec() поддержкой posix_spawn. wrapper.tanukisoftware.com/jdoc/org/tanukisoftware/wrapper /…

Ответ №1:

Последние версии Java 7 и 8 поддерживают posix_spawn внутренне.

параметр командной строки

 -Djdk.lang.Process.launchMechanism=POSIX_SPAWN
  

или включить во время выполнения

 System.setProperty("jdk.lang.Process.launchMechanism", "POSIX_SPAWN");
  

Я немного сбит с толку относительно того, в каких сочетаниях Java-версии / операционной системы это включено по умолчанию, но я уверен, что вы могли бы протестировать и довольно быстро выяснить, имеет ли значение установка этого параметра.

Для справки, чтобы вернуться к старому fork методу, просто используйте

 -Djdk.lang.Process.launchMechanism=fork
  

Чтобы доказать, соблюдается ли этот параметр в вашей версии JVM, используйте

 -Djdk.lang.Process.launchMechanism=dummy
  

и в следующий раз вы получите сообщение об ошибке exec . Таким образом, вы знаете, что JVM получает эту опцию.

Ответ №2:

Альтернативой, для которой не требуется JNI, является создание отдельного приложения «process spawner». Вероятно, я бы попросил это приложение предоставить интерфейс RMI и создать объект-оболочку, который является заменой для ProcessBuilder .

Возможно, вы также захотите рассмотреть возможность запуска вашего устаревшего приложения с помощью этого приложения-«спавнера».

Комментарии:

1. Знаете ли вы о каких-либо реализациях этого с открытым исходным кодом? Я нахожусь на грани написания одного из них сам, но я бы предпочел использовать библиотеку, если таковая существует.

Ответ №3:

Сначала вам нужно будет ознакомиться с JNI. Узнайте, как вызывать встроенную процедуру из кода Java. Как только вы это сделаете, вы можете посмотреть на этот пример и посмотреть, поможет ли это с вашей проблемой. Особый интерес для вас представляет:

 if( (RC=posix_spawn(amp;pid, spawnedArgs[0], NULL, NULL, spawnedArgs, NULL)) !=0 ){
    printf("Error while executing posix_spawn(), Return code from posix_spawn()=%d",RC);

}
  

Ответ №4:

Гораздо более простым решением было бы сохранить ваш код без изменений и просто добавить больше виртуальной памяти на ваш сервер.

т. е.:

 mkfile 2g /somewhere/swap-1
swap -a /somewhere/swap-1
  

Редактировать: для уточнения, поскольку ссылка, присутствующая в вопросе, теперь разорвана:

вопрос касается нехватки виртуальной памяти в системе из-за разветвления JVM. Например, предполагая, что JVM использует 2 ГБ виртуальной машины, для успешного выполнения форка на Solaris требуется еще 2 ГБ виртуальной машины. Здесь нет разбивки на страницы, просто резервирование памяти. В отличие от ядра Linux, которое по умолчанию перегружает память, Solaris гарантирует, что выделенная память поддерживается либо оперативной памятью, либо подкачкой. Поскольку подкачки недостаточно, происходит сбой fork. Увеличение подкачки позволяет выполнить форк успешно без какого-либо влияния на производительность. Сразу после форка exec «освобождает» эти 2 ГБ оперативной памяти и возвращается к ситуации, идентичной ситуации с posix_spawn.

Смотрите также эту страницу для объяснения распределения памяти в Solaris и других операционных системах.

Комментарии:

1. op спросил, как использовать posix spawn, а не как добавить виртуальную память

2. @kritzikratzi OP выявил проблему, и то, что я предлагаю, является гораздо более простым и менее навязчивым обходным путем, чем то, что он исследует. Ничего, что заслуживало бы отрицательного голосования.

3. замена на жесткий диск не является жизнеспособным вариантом, если скорость имеет лишь незначительное значение, вот почему я проголосовал против.

4. добавьте к этому: ваш ответ даже не устраняет проблему, потому что добавление пространства подкачки не имеет к ней никакого отношения. вам придется увеличить лимит Xmx и Xms, проблема может быть в нехватке места подкачки, а может и не быть.

5. @kritzikratzi Потому что вопрос касается нехватки виртуальной памяти в системе из-за разветвления JVM. Например, если JVM использует 2 ГБ виртуальной машины, требуется дополнительные 2 ГБ виртуальной машины. Здесь нет абсолютно никакой разбивки на страницы, просто резервирование памяти. Solaris гарантирует, что выделенная память поддерживается либо оперативной памятью, либо подкачкой. Поскольку подкачки недостаточно, происходит сбой fork. Увеличение подкачки позволяет выполнить форк успешно без какого-либо влияния на производительность. Сразу после форка exec «освобождает» эти 2 ГБ оперативной памяти и возвращается к ситуации, идентичной ситуации с posix_spawn.