Saya menguji jenkins-ci dengan sukses di ubuntu 10.4 (dengan vmware fusion) di komputer lokal saya. Sekarang saya ingin menginstal dan menggunakannya di server virtual saya di hosteurope. Instalasi dasar tidak masalah, tapi sekarang saya punya masalah dengan proyek build saya.
Setelah menarik pembaruan lincah dari repositori, semut dipanggil dan melempar kesalahan berikut dalam proyek build saya:
"Buildfile: /var/lib/jenkins/workspace/concrete5-seed-clean/build.xml [properti] java.io.IOException: Tidak dapat menjalankan program" / usr / bin / env ": java.io.IOException: error = 12, Tidak dapat mengalokasikan memori "
Ada masalah yang diketahui dengan ukuran tumpukan di server virtual di hosteurope ( http://faq.hosteurope.de/index.php?cpid=13918 ), jadi saya mencoba mengatur ukuran tumpukan secara manual:
# 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
Setelah mengatur ini untuk semut, perintah "ant -diagnostics" dijalankan dan tidak menyebabkan kesalahan, tetapi kesalahan masih terjadi ketika saya mencoba membangun proyek.
Rincian Server: - http://www.hosteurope.de/produkt/Virtual-Server-Linux-L
- Ubuntu 10.4 LTS
- RAM: 1GB / Dinamis 2GB
Pertanyaan saya: - Apakah 1GB cukup untuk Jenkins atau apakah saya harus memutakhirkan server? - Apakah kesalahan ini disebabkan oleh semut atau jenkins?
Pembaruan: Saya menjalankannya dengan opsi semut -Xmx128m -Xms128m, tetapi kadang-kadang kesalahan terjadi lagi. (Ini membuatku takut, karena aku tidak bisa mereproduksinya sekarang: /)
Bantuan sangat dihargai!
Cheers, Matthias
Jawaban:
Orien benar, ini adalah fork () system call yang dipicu oleh ProcessBuilder atau Runtime.exec atau cara lain dari JVM yang menjalankan proses eksternal (mis. JVM lain yang menjalankan semut, perintah git, dll.).
Ada beberapa posting di milis Jenkins tentang ini: Tidak dapat menjalankan program "git" ... error = 12, Tidak dapat mengalokasikan memori
Ada deskripsi yang bagus tentang masalah pada daftar dev SCons: fork () + exec () vs posix_spawn ()
Ada laporan bug JVM lama dengan solusi: Gunakan posix_spawn, bukan fork, pada S10 untuk menghindari pertukaran swap . Tapi saya tidak yakin apakah ini benar-benar berhasil masuk ke JDK7 karena komentarnya adalah rencananya.
Singkatnya, pada sistem mirip Unix, ketika satu proses (misalnya JVM) perlu meluncurkan proses lain (misalnya git) panggilan sistem dibuat
fork()
yang secara efektif menduplikasi proses saat ini dan semua memorinya (Linux dan yang lainnya mengoptimalkan ini dengan salinan -on-tulis sehingga memori tidak benar-benar disalin sampai anak mencoba menulis ke sana). Proses duplikat kemudian membuat panggilan sistem lain,exec()
untuk meluncurkan proses lain (misalnya git) di mana semua memori yang disalin dari proses induk dapat dibuang oleh sistem operasi. Jika proses induk menggunakan memori dalam jumlah besar (seperti proses JVM cenderung lakukan), panggilan untukfork()
dapat gagal jika sistem operasi menentukan tidak memiliki cukup memori + swap untuk menampung dua salinan, bahkan jika proses anak tidak akan pernah benar-benar gunakan memori yang disalin.Ada beberapa solusi:
Tambahkan lebih banyak memori fisik / RAM ke mesin.
Tambahkan lebih banyak ruang swap untuk mengelabui
fork()
bekerja, meskipun ruang swap tidak sepenuhnya diperlukan untuk apa pun. Ini adalah solusi yang saya pilih karena cukup mudah untuk menambahkan swapfile, dan saya tidak ingin hidup dengan potensi proses yang terbunuh karena terlalu banyak berkomitmen.Di Linux, aktifkan
overcommit_memory
opsi sistem vm ( / proc / sys / vm / overcommit_memory ). Dengan overcommit, panggilan untukfork()
selalu berhasil, dan karena proses anak sebenarnya tidak akan menggunakan salinan memori itu, semuanya baik-baik saja. Tentu saja, mungkin saja dengan overcommit, proses Anda akan benar-benar mencoba menggunakan lebih banyak memori daripada yang tersedia dan akan dibunuh oleh kernel. Apakah ini sesuai tergantung pada penggunaan lain dari mesin. Mesin misi kritis mungkin tidak boleh mengambil risiko pembunuh kehabisan memori menjalankan amuk. Tetapi server pengembangan internal yang mampu menghentikan beberapa waktu akan menjadi tempat yang baik untuk mengaktifkan overcommit.Ubah JVM untuk tidak menggunakan
fork()
+exec()
tetapi untuk menggunakanposix_spawn()
bila tersedia. Ini adalah solusi yang diminta dalam laporan bug JVM di atas dan disebutkan pada milis SCons. Ini juga diterapkan di java_posix_spawn .Saya mencoba mencari tahu apakah perbaikan itu berhasil masuk ke JDK7. Jika tidak, saya ingin tahu apakah orang-orang Jenkins akan tertarik pada pekerjaan di sekitar seperti java_posix_spawn. Tampaknya ada upaya untuk mengintegrasikannya ke dalam Apache commons-exec .
Programmieraffe, saya tidak 100% yakin, tetapi tautan Anda menyarankan perbaikan di JDK7 dan JDK6 1.6.0_23 dan yang lebih baru. Sebagai catatan, saya menjalankan OpenJDK 1.6.0_18.
Lihat /programming/1124771/how-to-solve-java-io-ioexception-error-12-cannot-allocate-memory-calling-run
sumber
Perhatikan pesan pengecualian:
Cannot run program "/usr/bin/env": java.io.IOException: error=12, Cannot allocate memory"
Proses Java mencoba untuk memotong proses baru untuk menjalankan perintah/usr/bin/env
tetapi sistem operasi telah kehabisan sumber daya memori untuk membuat proses baru. Ini tidak sama dengan Java VM kehabisan memori sehingga tidak ada jumlah mengutak-atik -Xmx akan memperbaikinya. Anda harus memonitor sumber daya memori Anda saat menjalankan build Anda. Meningkatkan ruang swap kemungkinan akan memperbaiki masalah Anda.sumber
Kemungkinan ANT_OPTS diganti oleh Jenkins. Anda juga dapat mengatur opsi langsung di file build Anda sehingga Anda dapat mengontrol alokasi memori secara independen dari lingkungan (shell, Jenkins, ...). Dalam file build Anda (contoh:
sumber