Дженкинс С.И. - Не удается выделить память

9

Я успешно протестировал jenkins-ci на Ubuntu 10.4 (с vmware fusion) на моем локальном компьютере. Теперь я хочу установить и использовать его на своем виртуальном сервере в hosteurope. Базовая установка не была проблемой, но теперь у меня проблемы с моим проектом сборки.

После извлечения обновления Mercurial из репозитория 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

  • Ubuntu 10.4 LTS
  • Оперативная память: 1 ГБ / динамическая 2 ГБ

Мои вопросы: - Достаточно ли 1 ГБ для Дженкинса или мне нужно обновить сервер? - Эта ошибка вызвана муравьем или Дженкинсом?

Обновление: я запустил его с параметрами муравья -Xmx128m -Xms128m, но иногда ошибка повторяется. (это меня бесит, потому что я не могу сейчас это воспроизвести: /)

Помощь очень ценится!

Ура, Матиас

Programmieraffe
источник
Я решил это, установив конфигурационные файлы jenkins: JENKINS_JAVA_OPTIONS = "- Djava.awt.headless = true -Xms500m -Xmx1000m"
herbertD

Ответы:

10

Ориен правильно, это системный вызов fork (), запускаемый ProcessBuilder или Runtime.exec или другими средствами JVM, выполняющими внешний процесс (например, другой JVM, выполняющий ant, команду git и т. Д.).

В списках рассылки Jenkins было несколько сообщений об этом: Не удается запустить программу "git" ... error = 12, Невозможно выделить память

В списке разработчиков SCons есть хорошее описание проблемы: fork () + exec () против posix_spawn ()

Существует давний отчет об ошибках JVM с решениями: используйте posix_spawn, а не fork на S10, чтобы избежать исчерпания свопинга . Но я не уверен, что это действительно вошло в JDK7, поскольку комментарии предполагают, что это был план.

Итак, в Unix-подобных системах, когда одному процессу (например, JVM) необходимо запустить другой процесс (например, git), выполняется системный вызов, fork()который эффективно дублирует текущий процесс и всю его память (Linux и другие оптимизируют это с помощью копирования). -на записи, чтобы память фактически не копировалась, пока ребенок не попытается записать в нее). Затем дублирующий процесс выполняет другой системный вызов, exec()чтобы запустить другой процесс (например, git), после чего вся эта скопированная память из родительского процесса может быть отброшена операционной системой. Если родительский процесс использует большие объемы памяти (как это обычно делают процессы JVM), вызов fork()может завершиться ошибкой, если операционная система определит, что ему не хватает памяти + swap для хранения двух копий, даже если дочерний процесс никогда не будет фактически использовать эту скопированную память.

Есть несколько решений:

  • Добавьте больше физической памяти / RAM к машине.

  • Добавьте больше пространства подкачки, чтобы обманным путем заставить fork()работать, даже если пространство подкачки ни в чем не нуждается строго. Это решение, которое я выбрал, потому что довольно легко добавить файл подкачки, и я не хотел мириться с возможностью того, что процессы будут убиты из-за чрезмерной загрузки.

  • В Linux включите overcommit_memoryопцию системы vm ( / proc / sys / vm / overcommit_memory ). При использовании overcommit вызов fork()всегда будет успешным, и поскольку дочерний процесс фактически не будет использовать эту копию памяти, все в порядке. Конечно, возможно, что при чрезмерной загрузке ваши процессы будут пытаться использовать больше памяти, чем доступно, и будут убиты ядром. Уместно ли это, зависит от других применений машины. Критически важные машины, вероятно, не должны рисковать убийцей нехватки памяти. Но внутренний сервер разработки, который может позволить себе некоторое время простоя, был бы хорошим местом для включения overcommit.

  • Измените 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.

См. Https://stackoverflow.com/questions/1124771/how-to-solve-java-io-ioexception-error-12-cannot-allocate-memory-calling-run

Патрик
источник
Спасибо за подробный ответ! В соответствующем сообщении Альф Хегемарк говорит, что это сейчас исправлено: ( stackoverflow.com/a/9127548/809939 ) Кто-нибудь может это подтвердить? Я постараюсь обновить мою версию Java, а также.
Programmieraffe
Дополнительный вопрос: что бы вы предложили? Overcommit-память-настройка? С уважением, Маттиас
Programmieraffe
1
Добавить файл подкачки легко и просто. Для Ubuntu 12.04 (хотя он должен применяться в основном для Linux в целом), эта статья была мертва проста: digitalocean.com/community/articles/...
davemyron
1

Обратите внимание на сообщение об исключении: Cannot run program "/usr/bin/env": java.io.IOException: error=12, Cannot allocate memory"Java-процесс пытается запустить новый процесс для запуска команды, /usr/bin/envно операционная система исчерпала ресурсы памяти для создания нового процесса. Это не то же самое, что нехватка памяти на виртуальной машине Java, поэтому никакие проблемы с флагами -Xmx не исправят это. Вам нужно будет следить за ресурсами памяти во время сборки. Увеличение пространства подкачки, скорее всего, решит вашу проблему.

Orien
источник
Это виртуальная машина Java (одна из куч или стеков), которой не хватает памяти, а не хост-компьютер.
MDPC
Извините за краткость моего оригинального ответа. Я обновил его, чтобы описать, почему в JVM не хватает памяти.
Ориентир
0

Вероятно, что ANT_OPTS переопределены Jenkins. Вы также можете установить параметры непосредственно в файле сборки, чтобы вы могли контролировать выделение памяти независимо от среды (shell, Jenkins, ...). В вашем файле сборки (пример:

<java fork="true" classname="..." >
    <jvmarg line="-Xms512M -Xmx512M" />
Matteo
источник