Jenkins CI - Bellek ayrılamıyor


9

Yerel bilgisayarımda ubuntu 10.4 (vmware fusion ile) üzerinde jenkins-ci'yi başarıyla test ettim. Şimdi hosteurope'daki sanal sunucuma kurmak ve kullanmak istiyorum. Temel kurulum sorun değildi, ama şimdi inşa projemle ilgili problemlerim var.

Bir havuzdan cıva güncellemesini çektikten sonra karınca çağrılır ve derleme projemde aşağıdaki hatayı atar:

"Buildfile: /var/lib/jenkins/workspace/concrete5-seed-clean/build.xml [özellik] java.io.IOException: Program çalıştırılamıyor" / usr / bin / env ": java.io.IOException: error = 12, bellek ayrılamıyor "

Hosteurope ( http://faq.hosteurope.de/index.php?cpid=13918 ) sanal sunucularında yığın boyutu ile ilgili bilinen bir sorun var , bu yüzden yığın boyutunu manuel olarak ayarlamaya çalıştım:

# 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 

Bunu ant için ayarladıktan sonra, "ant -diagnostics" komutu çalışır ve hataya neden olmaz, ancak projeyi oluşturmaya çalıştığımda hata yine de oluşur.

Sunucu Detayları: - http://www.hosteurope.de/produkt/Virtual-Server-Linux-L

  • Ubuntu 10.4 LTS
  • RAM: 1 GB / Dinamik 2 GB

Sorularım: - Jenkins için 1 GB yeterli mi yoksa sunucuyu yükseltmem gerekiyor mu? - Bu hata karınca veya cenkinlerden mi kaynaklanıyor?

Güncelleme: -Xmx128m -Xms128m karınca seçenekleriyle çalıştırıyorum, ancak bazen hata tekrar ortaya çıkıyor. (bu beni korkutuyor, çünkü şimdiye kadar çoğaltamıyorum: /)

Çok takdir Yardım!

Şerefe, Matthias


Bunu set jenkins yapılandırma dosyaları ile çözdüm: JENKINS_JAVA_OPTIONS = "- Djava.awt.headless = true -Xms500m -Xmx1000m"
herbertD

Yanıtlar:


10

Orien doğrudur, ProcessBuilder veya Runtime.exec veya harici bir işlemi yürüten JVM'nin diğer araçları (örn. Başka bir JVM çalışan karınca, git komutu, vb.) Tarafından tetiklenen fork () sistem çağrısıdır.

Jenkins posta listelerinde bu konuda bazı mesajlar var: "git" programı çalıştırılamıyor ... error = 12, Bellek ayrılamıyor

SCons dev listesinde sorunun güzel bir açıklaması var: fork () + exec () vs posix_spawn ()

Çözümleri olan uzun süredir devam eden bir JVM hata raporu var: Takas tükenmesini önlemek için S10'da çatal değil posix_spawn kullanın . Ama yorumların önerdiği planın JDK7'ye dönüştürüp dönüştürmediğinden emin değilim.

Özetle, Unix benzeri sistemlerde, bir işlemin (örn. JVM) başka bir işlem başlatması gerektiğinde (örn. Git) fork(), geçerli işlemi ve tüm belleğini etkili bir şekilde kopyalayan bir sistem çağrısı yapılır (Linux ve diğerleri bunu kopya ile optimize eder) -on-yazma böylece bellek aslında çocuk yazmaya çalışana kadar kopyalanmaz). Yinelenen işlem daha sonra exec(), üst işlemden kopyalanan tüm belleğin işletim sistemi tarafından atılabileceği diğer işlemi (örn. Git) başlatmak için başka bir sistem çağrısı yapar . Üst işlem büyük miktarda bellek kullanıyorsa (JVM işlemlerinin yapma eğiliminde olduğu gibi), fork()işletim sistemi, alt işlem asla gerçekte olmayacak olsa bile, iki kopya için yeterli bellek + takas olmadığını belirlerse çağrı başarısız olabilir. kopyalanan hafızayı kullanın.

Birkaç çözüm var:

  • Makineye daha fazla fiziksel bellek / RAM ekleyin.

  • Takas alanı fork()herhangi bir şey için kesinlikle gerekli olmamasına rağmen, çalışmayı kandırmak için daha fazla takas alanı ekleyin . Bu, seçtiğim çözümdür, çünkü bir swapfile eklemek oldukça kolaydır ve fazla taahhüt nedeniyle öldürülen süreçlerin potansiyeli ile yaşamak istemedim.

  • Linux'ta overcommit_memoryvm sistemi seçeneğini etkinleştirin ( / proc / sys / vm / overcommit_memory ). Fazla taahhüt ile çağrı fork()her zaman başarılı olur ve alt süreç aslında belleğin bu kopyasını kullanmayacağından, her şey yolundadır. Tabii ki, aşırı taahhüt ile süreçlerinizin aslında mevcut olandan daha fazla bellek kullanmaya çalışması ve çekirdek tarafından öldürülmesi mümkündür. Bunun uygun olup olmadığı, makinenin diğer kullanımlarına bağlıdır. Kritik görev makineleri, muhtemelen hafızası bitmiş katili amok ile riske atmamalıdır. Ancak, bir süre kesinti sağlayabilecek bir iç geliştirme sunucusu, fazla çalışmayı sağlamak için iyi bir yer olacaktır.

  • JVM'yi fork()+ exec()değil, kullanılabilir posix_spawn()olduğunda kullanacak şekilde değiştirin. Bu, yukarıdaki JVM hata raporunda istenen ve SCons posta listesinde belirtilen çözümdür. Ayrıca java_posix_spawn içinde uygulanır .

    Bu düzeltmenin JDK7'ye yapılıp yapılmadığını öğrenmeye çalışıyorum. Değilse, Jenkins insanların java_posix_spawn gibi bir çalışma ile ilgilenip ilgilenmeyeceğini merak ediyorum. Bunu Apache commons-exec ile entegre etme girişimleri var gibi görünüyor .

    Programmieraffe,% 100 emin değilim, ancak bağlantınız düzeltmenin JDK7 ve JDK6 1.6.0_23 ve sonrasında olduğunu gösteriyor. Kayıt için OpenJDK 1.6.0_18 kullanıyordum.

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


Ayrıntılı cevap için teşekkürler! İlgili yazıda Alf Høgemark bunun düzeltildiğini söylüyor: ( stackoverflow.com/a/9127548/809939 ) Birisi bunu onaylayabilir mi? Java sürümümü de güncellemeye çalışacağım.
Programmieraffe

Ek soru: Ne önerirsiniz? Overcommit-Bellek-Ayar? Saygılarımızla, Matthias
Programmieraffe

1
Bir swapfile eklemek kolay ve basittir. Ubuntu 12.04 için (genel olarak Linux için büyük ölçüde geçerli olsa da), bu makale çok basitti: digitalocean.com/community/articles/…
davemyron

1

Özel durum iletisine dikkat edin: Cannot run program "/usr/bin/env": java.io.IOException: error=12, Cannot allocate memory"Java işlemi komutu çalıştırmak için yeni bir işlem yapmaya çalışıyor /usr/bin/envancak işletim sisteminde yeni bir işlem oluşturmak için bellek kaynakları tükenmiştir. Bu, bellek yetersiz kalan Java VM ile aynı değildir, bu nedenle -Xmx bayraklarıyla uğraşmak için hiçbir sorun çözülmez. Derlemenizi çalıştırırken bellek kaynaklarınızı izlemeniz gerekir. Takas alanını artırmak muhtemelen sorununuzu çözecektir.


Ana bilgisayar sistemi DEĞİL bellek yetersiz Java Sanal makine (yığın veya yığınlardan biri).
mdpc

Özgün cevabımın özünü affedin. Neden bellekte yetersiz JVM olmadığını açıklamak için güncelledim.
orien

0

ANT_OPTS, Jenkins tarafından geçersiz kılınmış olabilir. Ayrıca, bellek ayırmayı ortamdan bağımsız olarak (kabuk, Jenkins, ...) kontrol edebilmeniz için seçenekleri doğrudan oluşturma dosyanızda da ayarlayabilirsiniz. Derleme dosyanızda (örnek:

<java fork="true" classname="..." >
    <jvmarg line="-Xms512M -Xmx512M" />
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.