Я успешно протестировал jenkins-ci на ubuntu 10.4 (с vmware fusion) на моем локальном компьютере. Теперь я хочу установить и использовать его на моем виртуальном сервере в hosteurope. Базовая установка не была проблемой, но теперь у меня проблемы с моим проектом сборки.
После получения ртутного обновления из репозитория вызывается ant и выдает следующую ошибку в моем проекте сборки:
"Файл сборки: /var/lib/jenkins/workspace/concrete5-seed-clean/build.xml [свойство] java.io.IOException: не удается запустить программу" / usr / bin / env ": java.io.IOException: error = 12. Невозможно выделить память »
Известная проблема с размером кучи на виртуальных серверах в hosteurope (http://faq.hosteurope.de/index.php?cpid=13918), поэтому я попытался установить размер кучи вручную:
# for ant
export ANT_OPTS="-Xms512m -Xmx512m"
# jenkins
# edited /etc/default/jenkins, added line
JAVA_ARGS="-Xms512m -Xmx512m"
# restarted jenkins via /etc/init.d/jenkins restart
После установки этого параметра для ant выполняется команда ant -diagnostics, которая не вызывает ошибки, но ошибка по-прежнему возникает, когда я пытаюсь построить проект.
Сведения о сервере: - http://www.hosteurope.de/produkt/Virtual-Server-Linux-L
Мои вопросы: - Достаточно ли 1 ГБ для Jenkins или мне нужно обновить сервер? - Эта ошибка вызвана муравьем или дженкинсом?
Обновление: я запустил его с параметрами ant -Xmx128m -Xms128m, но иногда ошибка возникает снова. (это меня пугает, потому что я не могу воспроизвести его сейчас: /)
Помощь очень ценится!
Ура, Матиас
Ориен верен, это системный вызов fork (), запускаемый ProcessBuilder или Runtime.exec или другими средствами JVM, выполняющими внешний процесс (например, другой JVM, на котором запущен ant, команда git и т. Д.).
В списках рассылки Jenkins было несколько сообщений об этом: Не удается запустить программу "git" ... ошибка = 12, не удается выделить память
В списке разработчиков SCons есть хорошее описание проблемы: fork () + exec () против posix_spawn ()
Существует давний отчет об ошибке JVM с решениями: Используйте posix_spawn, а не fork, на S10, чтобы избежать исчерпания свопа. Но я не уверен, действительно ли это вошло в JDK7, поскольку комментарии предполагают, что это был план.
Таким образом, в Unix-подобных системах, когда одному процессу (например, JVM) необходимо запустить другой процесс (например, git), выполняется системный вызов fork()
который эффективно дублирует текущий процесс и всю его память (Linux и другие оптимизируют это с помощью копирования при записи, поэтому память фактически не копируется, пока дочерний процесс не попытается записать в него). Затем дублированный процесс выполняет другой системный вызов, exec()
для запуска другого процесса (например, git), после чего вся скопированная память из родительского процесса может быть удалена операционной системой. Если родительский процесс использует большой объем памяти (как это обычно делают процессы JVM), вызов fork()
может завершиться ошибкой, если операционная система определит, что у нее недостаточно памяти + подкачки для хранения двух копий, даже если дочерний процесс никогда не будет фактически использовать эту скопированную память.
Есть несколько решений:
Добавьте на машину больше физической памяти / ОЗУ.
Добавьте больше места подкачки, чтобы обмануть fork()
в работу, хотя пространство подкачки ни для чего строго не требуется. Это решение, которое я выбрал, потому что добавить файл подкачки довольно просто, и я не хотел мириться с тем, что процессы могут быть убиты из-за чрезмерной фиксации.
В Linux включите overcommit_memory
вариант системы vm (/ proc / sys / vm / overcommit_memory). При сверхкоммите вызов fork()
всегда будет успешным, и поскольку дочерний процесс на самом деле не будет использовать эту копию памяти, все в порядке. Конечно, возможно, что из-за чрезмерной фиксации ваши процессы фактически попытаются использовать больше памяти, чем доступно, и будут убиты ядром. Уместно ли это, зависит от других вариантов использования машины. Критически важные машины, вероятно, не должны рисковать выходом из-под контроля нехватки памяти. Но внутренний сервер разработки, который может позволить себе некоторое время простоя, был бы хорошим местом для включения чрезмерной нагрузки.
Измените JVM, чтобы не использовать fork()
+exec()
но использовать posix_spawn()
по мере доступности. Это решение, запрошенное в отчете об ошибке JVM выше и упомянутое в списке рассылки SCons. Это также реализовано в java_posix_spawn.
Я пытаюсь выяснить, вошло ли это исправление в JDK7. Если нет, мне интересно, были бы люди из Дженкинса заинтересованы в такой работе, как java_posix_spawn. Похоже, были попытки интегрировать это в Apache Commons-exec.
Programmieraffe, я не уверен на 100%, но ваша ссылка предполагает, что исправление находится в JDK7 и JDK6 1.6.0_23 и более поздних версиях. Для справки, я использовал OpenJDK 1.6.0_18.
Обратите внимание на сообщение об исключении: Cannot run program "/usr/bin/env": java.io.IOException: error=12, Cannot allocate memory"
Процесс Java пытается создать новый процесс для выполнения команды /usr/bin/env
но у операционной системы закончились ресурсы памяти для создания нового процесса. Это не то же самое, что виртуальной машине Java, у которой не хватает памяти, поэтому никакие возни с флагами -Xmx не исправят. Вам нужно будет контролировать ресурсы вашей памяти во время выполнения сборки. Увеличение объема подкачки скорее всего решит вашу проблему.
Вероятно, что ANT_OPTS переопределены Jenkins. Вы также можете установить параметры непосредственно в файле сборки, чтобы вы могли контролировать выделение памяти независимо от среды (оболочка, Jenkins, ...). В вашем файле сборки (пример:
<java fork="true" classname="..." >
<jvmarg line="-Xms512M -Xmx512M" />