Jenkins CI-メモリを割り当てることができません


9

ローカルコンピューターのubuntu 10.4(vmware fusionを使用)でjenkins-ciを正常にテストしました。これを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

  • Ubuntu 10.4 LTS
  • RAM:1GB /ダイナミック2GB

私の質問:-Jenkinsには1GBで十分ですか、それともサーバーをアップグレードする必要がありますか?-このエラーはantまたはjenkinsが原因ですか?

更新:Antオプション-Xmx128m -Xms128mで実行しましたが、エラーが再度発生することがあります。(これは私を驚かせます、私は今ではそれを再現できないので:/)

どうぞよろしくお願いいたします。

乾杯、マティアス


私はjenkins設定ファイルを設定することでこれを解決しました:JENKINS_JAVA_OPTIONS = "-Djava.awt.headless = true -Xms500m -Xmx1000m"
herbertD

回答:


10

Orienは正解です。これは、ProcessBuilder、Runtime.exec、または外部プロセスを実行しているJVMの他の手段(antを実行している別のJVM、gitコマンドなど)によってトリガーされるfork()システムコールです。

Jenkinsメーリングリストにいくつかの投稿があります:プログラム "git"を実行できません...エラー= 12、メモリを割り当てることができません

SCons devリストに問題の良い説明があります:fork()+ exec()とposix_spawn()

解決策に関する長年のJVMバグレポートがあります。S10でforkではなくposix_spawnを使用して、スワップの枯渇を回避します。しかし、コメントが計画通りだったので、これが実際にJDK7になったかどうかはわかりません。

要約すると、Unixライクなシステムでは、1つのプロセス(JVMなど)が別のプロセス(Gitなど)を起動する必要がある場合fork()、現在のプロセスとそのすべてのメモリを効果的に複製するシステムコールが行われます(Linuxなどは、これをコピーで最適化します) -on-writeので、子が書き込みを試みるまで、メモリは実際にはコピーされません)。次に、複製プロセスは別のシステムコールを実行exec()して、他のプロセス(gitなど)を起動します。この時点で、親プロセスからコピーされたすべてのメモリがオペレーティングシステムによって破棄されます。親プロセスが大量のメモリを使用している場合(JVMプロセスはそうする傾向があるため)、fork()子プロセスが実際には決して実行されない場合でも、オペレーティングシステムが2つのコピーを保持するのに十分なメモリ+スワップを持たないとオペレーティングシステムが判断した場合、そのコピーされたメモリを使用します。

いくつかの解決策があります:

  • マシンに物理メモリ/ RAMを追加します。

  • スワップスペースを追加fork()して、をだまして動作させます。スワップスペースは厳密には何も必要ではありません。これは、スワップファイルを追加するのがかなり簡単であり、オーバーコミットのためにプロセスが強制終了される可能性を我慢したくなかったため、私が選択したソリューションです。

  • Linuxでは、overcommit_memoryvmシステムのオプションを有効にします(/ proc / sys / vm / overcommit_memory)。オーバーコミットを使用すると、への呼び出しfork()は常に成功し、子プロセスは実際にはメモリのそのコピーを使用しないため、すべて順調です。もちろん、オーバーコミットにより、プロセスが実際に利用可能なメモリよりも多くのメモリを使用しようとし、カーネルによって強制終了される可能性があります。これが適切かどうかは、マシンの他の用途によって異なります。ミッションクリティカルなマシンは、メモリ不足のキラーが暴走する危険を冒してはいけません。ただし、ある程度のダウンタイムを許容できる内部開発サーバーは、オーバーコミットを有効にするのに適した場所です。

  • fork()+ exec()を使用せずposix_spawn()、可能な場合は使用するようにJVMを変更します。これは、上記のJVMバグレポートで要求され、SConsメーリングリストで言及されている解決策です。また、java_posix_spawnにも実装されています

    その修正がJDK7に組み込まれたかどうかを確認しようとしています。そうでなければ、Jenkinsの人々は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を参照してください


詳細な回答をありがとう!関連する投稿で、AlfHøgemarkはこれが修正されたと述べています:(stackoverflow.com/a/9127548/809939)誰かがこれを確認できますか?私も私のJavaバージョンを更新しようとします。
Programmieraffe

追加の質問:何を提案しますか?オーバーコミットメモリ設定?よろしく、マティアス
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仮想マシン(ヒープまたはスタックの1つ)です。
mdpc

私の元の答えの簡潔さを失ってください。JVMがメモリ不足にならない理由を説明するために更新しました。
オリエン

0

ANT_OPTSがJenkinsによってオーバーライドされる可能性があります。ビルドファイルで直接オプションを設定して、環境(シェル、Jenkinsなど)から独立してメモリ割り当てを制御することもできます。ビルドファイル内(例:

<java fork="true" classname="..." >
    <jvmarg line="-Xms512M -Xmx512M" />
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.