Probé jenkins-ci con éxito en un ubuntu 10.4 (con vmware fusion) en mi computadora local. Ahora quiero instalarlo y usarlo en mi servidor virtual en hosteurope. La instalación básica no fue un problema, pero ahora tengo problemas con mi proyecto de compilación.
Después de extraer una actualización mercurial de un repositorio, se invoca ant y arroja el siguiente error en mi proyecto de compilación:
"Buildfile: /var/lib/jenkins/workspace/concrete5-seed-clean/build.xml [propiedad] java.io.IOException: No se puede ejecutar el programa" / usr / bin / env ": java.io.IOException: error = 12, no se puede asignar memoria "
Existe un problema conocido con el tamaño de almacenamiento dinámico en los servidores virtuales en hosteurope ( http://faq.hosteurope.de/index.php?cpid=13918 ), así que intenté configurar el tamaño de almacenamiento dinámico manualmente:
# 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
Después de configurar esto para ant, el comando "ant -diagnostics" se ejecuta y no causa un error, pero el error aún ocurre cuando intento construir el proyecto.
Detalles del servidor: - http://www.hosteurope.de/produkt/Virtual-Server-Linux-L
- Ubuntu 10.4 LTS
- RAM: 1 GB / 2 GB dinámico
Mis preguntas: - ¿Es 1GB suficiente para Jenkins o tengo que actualizar el servidor? - ¿Es este error causado por hormiga o jenkins?
Actualización: lo ejecuté con las opciones ant -Xmx128m -Xms128m, pero a veces el error ocurre nuevamente. (Esto me asusta, porque no puedo reproducirlo por ahora: /)
Ayuda muy apreciada!
Saludos, Matías
Respuestas:
Orien es correcto, es la llamada al sistema fork () activada por ProcessBuilder o Runtime.exec u otros medios de la JVM que ejecuta un proceso externo (por ejemplo, otra JVM que ejecuta una hormiga, un comando git, etc.).
Ha habido algunas publicaciones en las listas de correo de Jenkins sobre esto: No se puede ejecutar el programa "git" ... error = 12, No se puede asignar memoria
Hay una buena descripción del problema en la lista de desarrolladores de SCons: fork () + exec () vs posix_spawn ()
Hay un informe de errores JVM de larga data con soluciones: use posix_spawn, no fork, en S10 para evitar el agotamiento del intercambio . Pero no estoy seguro de si esto realmente llegó a JDK7, ya que los comentarios sugieren que era el plan.
En resumen, en sistemas tipo Unix, cuando un proceso (por ejemplo, la JVM) necesita lanzar otro proceso (por ejemplo, git) se realiza una llamada al sistema
fork()
que duplica efectivamente el proceso actual y toda su memoria (Linux y otros optimizan esto con copia -on-write para que la memoria no se copie realmente hasta que el niño intente escribirle). Luego, el proceso duplicado realiza otra llamada al sistemaexec()
para iniciar el otro proceso (por ejemplo, git), en cuyo punto el sistema operativo puede descartar toda la memoria copiada del proceso principal. Si el proceso principal está utilizando grandes cantidades de memoria (como suelen hacer los procesos JVM), la llamada afork()
puede fallar si el sistema operativo determina que no tiene suficiente memoria + intercambio para contener dos copias, incluso si el proceso secundario nunca realmente usa esa memoria copiada.Hay varias soluciones:
Agregue más memoria física / RAM a la máquina.
Agregue más espacio de intercambio para engañar
fork()
al trabajo, aunque el espacio de intercambio no sea estrictamente necesario para nada. Esta es la solución que elegí porque es bastante fácil agregar un archivo de intercambio, y no quería vivir con el potencial de que los procesos se maten debido a un exceso de compromiso.En Linux, habilite la
overcommit_memory
opción del sistema vm ( / proc / sys / vm / overcommit_memory ). Con el sobrecompromiso, la llamada afork()
siempre tendrá éxito, y dado que el proceso secundario en realidad no va a usar esa copia de la memoria, todo está bien. Por supuesto, es posible que con un exceso de compromiso, sus procesos realmente intenten usar más memoria de la que está disponible y el núcleo los eliminará. Si esto es apropiado depende de los otros usos de la máquina. Las máquinas de misión crítica probablemente no deberían arriesgarse a que el asesino sin memoria se vuelva loco. Pero un servidor de desarrollo interno que pueda permitirse un tiempo de inactividad sería un buen lugar para habilitar el exceso de compromiso.Cambie la JVM para que no use
fork()
+exec()
sino para usarposix_spawn()
cuando esté disponible. Esta es la solución solicitada en el informe de errores de JVM mencionado anteriormente y mencionado en la lista de correo SCons. También se implementa en java_posix_spawn .Estoy tratando de averiguar si esa solución llegó a JDK7. Si no, me pregunto si la gente de Jenkins estaría interesada en una solución como java_posix_spawn. Parece haber habido intentos de integrar eso en Apache commons-exec .
Programmieraffe, no estoy 100% seguro, pero su enlace sugiere que la solución está en JDK7 y JDK6 1.6.0_23 y posteriores. Para el registro, estaba ejecutando OpenJDK 1.6.0_18.
Ver /programming/1124771/how-to-solve-java-io-ioexception-error-12-cannot-allocate-memory-calling-run
fuente
Tenga en cuenta el mensaje de excepción:
Cannot run program "/usr/bin/env": java.io.IOException: error=12, Cannot allocate memory"
el proceso Java está tratando de bifurcar un nuevo proceso para ejecutar el comando,/usr/bin/env
pero el sistema operativo se ha quedado sin recursos de memoria para crear un nuevo proceso. Esto no es lo mismo que la máquina virtual Java que se está quedando sin memoria, por lo que ninguna cantidad de retoques con banderas -Xmx lo solucionará. Tendrá que controlar sus recursos de memoria mientras ejecuta su compilación. Aumentar el espacio de intercambio probablemente solucionará su problema.fuente
Es probable que Jenkins anule ANT_OPTS. También puede configurar las opciones directamente en su archivo de compilación para que pueda controlar la asignación de memoria independientemente del entorno (shell, Jenkins, ...). En su archivo de compilación (ejemplo:
fuente