Jenkins CI - Неможливо виділити пам'ять


9

Я успішно протестував jenkins-ci на ubuntu 10.4 (з vmware fusion) на своєму локальному комп'ютері. Тепер я хочу встановити та використовувати його на своєму віртуальному сервері в хостевропі. Основна установка не була проблемою, але тепер у мене є проблеми з моїм проектом збірки.

Після витягування оновленого оновлення із сховища викликається мураха і видає таку помилку в моєму проекті збирання:

"Buildfile: /var/lib/jenkins/workspace/concrete5-seed-clean/build.xml [властивість] java.io.IOException: Неможливо запустити програму" / usr / bin / env ": java.io.IOException: error = 12, Неможливо виділити пам'ять "

Існує відома проблема з розміром купи на віртуальних серверах в хостевропі ( 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, але іноді помилка виникає знову. (це мене лякає, тому що я не можу його відтворити на даний момент: /)

Допомога високо оцінена!

Ура, Маттіас


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

Відповіді:


10

Orien правильний, це системний виклик fork (), ініційований ProcessBuilder або Runtime.exec або іншими засобами JVM, виконуючи зовнішній процес (наприклад, інший запущений мурашник JVM, команда git тощо).

У списках розсилки Дженкінса про це були деякі повідомлення: Неможливо запустити програму "git" ... помилка = 12, Неможливо виділити пам'ять

У списку розробників SCons є приємний опис випуску: fork () + exec () vs posix_spawn ()

Існує давній звіт про помилки JVM з рішеннями: Використовуйте posix_spawn, а не вилку, на S10, щоб уникнути виснаження свопів . Але я не впевнений, чи це насправді ввійшло в JDK7, як підказують коментарі.

Підсумовуючи це, у Unix-подібних системах, коли одному процесу (наприклад, JVM) потрібно запустити інший процес (наприклад, git), робиться системний виклик, fork()який ефективно дублює поточний процес і всю його пам'ять (Linux та інші оптимізують це за допомогою копії -напишіть, щоб пам'ять насправді не була скопійована, поки дитина не спробує записати на неї). Потім дублюючий процес робить інший системний виклик, exec()щоб запустити інший процес (наприклад, git), і тоді вся операція, що скопіювала пам'ять з батьківського процесу, може бути відкинута операційною системою. Якщо батьківський процес використовує велику кількість пам’яті (як це робиться в процесах JVM), виклик fork()може не вдатися, якщо операційна система визначить, що у нього не вистачає пам’яті + своп для зберігання двох копій, навіть якщо дочірній процес ніколи насправді не буде використовувати цю скопійовану пам'ять.

Є кілька рішень:

  • Додайте в машину більше фізичної пам’яті / оперативної пам’яті.

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

  • В Linux ввімкніть overcommit_memoryопцію системи vm ( / proc / sys / vm / overcommit_memory ). З надмірним доступом, заклик до fork()цього завжди буде успішним, і оскільки дочірній процес насправді не збирається використовувати цю копію пам'яті, все добре. Звичайно, можливо, що при надмірній передачі, ваші процеси будуть намагатися використовувати більше пам'яті, ніж доступно, і буде вбито ядром. Наскільки це підходить, залежить від інших застосувань машини. Машини з критичною місією, ймовірно, не повинні загрожувати вбивці поза пам'яттю під керуванням amok. Але внутрішній сервер розробки, який може дозволити собі час простою, був би хорошим місцем для включення перевиконання.

  • Змініть 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.

Дивіться /programming/1124771/how-to-solve-java-io-ioexception-error-12-cannot-allocate-memory-calling-run


Дякуємо за детальну відповідь! У відповідному дописі Альф Хегемарк говорить, що це зараз виправлено: ( stackoverflow.com/a/9127548/809939 ) Чи може хтось це підтвердити? Я спробую також оновити свою версію Java.
Programmieraffe

Додаткове запитання: Що б ви запропонували? Overcommit-Memory-Setting? З повагою, Маттіас
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 VM не вистачає пам’яті, тому жодна кількість фідінгу з прапорцями -Xmx не виправить це. Вам потрібно буде стежити за ресурсами пам’яті під час запуску збірки. Збільшення місця заміни, ймовірно, вирішить вашу проблему.


Це віртуальна машина Java (одна з купи або стеки), яка не має пам'яті, а не хост-комп'ютерна система.
mdpc

Вибачте за стислість моєї оригінальної відповіді. Я оновив його, щоб описати, чому в JVM не вистачає пам'яті.
orien

0

Ймовірно, що Дженкінс перекриває ANT_OPTS. Ви також можете встановити параметри безпосередньо у вашому файлі збірки, щоб ви могли контролювати розподіл пам'яті незалежно від оточення (оболонка, Дженкінс, ...). У вашому файлі збірки (приклад:

<java fork="true" classname="..." >
    <jvmarg line="-Xms512M -Xmx512M" />
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.