Testei o jenkins-ci com sucesso em um ubuntu 10.4 (com fusão de vmware) no meu computador local. Agora eu quero instalar e usá-lo no meu servidor virtual na hosteurope. A instalação básica não foi um problema, mas agora tenho problemas com meu projeto de construção.
Depois de extrair uma atualização mercurial de um repositório, o ant é invocado e lança o seguinte erro no meu projeto de construção:
"Buildfile: /var/lib/jenkins/workspace/concrete5-seed-clean/build.xml [propriedade] java.io.IOException: Não é possível executar o programa" / usr / bin / env ": java.io.IOException: error = 12, não é possível alocar memória "
Há um problema conhecido com o tamanho da pilha nos servidores virtuais em hosteurope ( http://faq.hosteurope.de/index.php?cpid=13918 ), então tentei definir o tamanho da pilha 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
Depois de definir isso para ant, o comando "ant -diagnostics" é executado e não causa um erro, mas o erro ainda ocorre quando tento criar o projeto.
Detalhes do servidor: - http://www.hosteurope.de/produkt/Virtual-Server-Linux-L
- Ubuntu 10.4 LTS
- RAM: 1 GB / 2 GB Dinâmicos
Minhas perguntas: - 1 GB é suficiente para Jenkins ou preciso atualizar o servidor? - Esse erro é causado por formigas ou jenkins?
Atualização: eu consegui rodar com as opções de formiga -Xmx128m -Xms128m, mas às vezes o erro ocorre novamente. (isso me assusta, porque eu não posso reproduzi-lo agora: /)
Ajuda muito apreciada!
Saúde, Matthias
Respostas:
Orien está correto, é a chamada do sistema fork () acionada pelo ProcessBuilder ou Runtime.exec ou outros meios da JVM executando um processo externo (por exemplo, outra JVM executando ant, um comando git, etc.).
Houve algumas postagens nas listas de discussão Jenkins sobre isso: Não é possível executar o programa "git" ... erro = 12, Não é possível alocar memória
Há uma boa descrição do problema na lista de desenvolvedores do SCons: fork () + exec () vs posix_spawn ()
Há um longo relatório de bug da JVM com soluções: Use posix_spawn, não fork, no S10 para evitar a exaustão da troca . Mas não tenho certeza se isso realmente chegou ao JDK7, pois os comentários sugerem que era o plano.
Em resumo, em sistemas do tipo Unix, quando um processo (por exemplo, a JVM) precisa iniciar outro processo (por exemplo, git), é feita uma chamada para o sistema
fork()
que duplica efetivamente o processo atual e toda a sua memória (Linux e outros otimizam isso com cópia) -on-write para que a memória não seja realmente copiada até que a criança tente gravá-la). O processo duplicado faz outra chamada do sistema,exec()
para iniciar o outro processo (por exemplo, git), no ponto em que toda a memória copiada do processo pai pode ser descartada pelo sistema operacional. Se o processo pai estiver usando grandes quantidades de memória (como costumam fazer os processos da JVM), a chamadafork()
poderá falhar se o sistema operacional determinar que não há memória suficiente + troca para armazenar duas cópias, mesmo se o processo filho nunca realmente use essa memória copiada.Existem várias soluções:
Adicione mais memória física / RAM à máquina.
Adicione mais espaço de troca para que o
fork()
trabalho funcione, mesmo que o espaço de troca não seja estritamente necessário para nada. Esta é a solução que eu escolhi porque é bastante fácil adicionar um arquivo de troca e não queria viver com o potencial de processos serem eliminados devido à confirmação excessiva.No Linux, ative a
overcommit_memory
opção do sistema vm ( / proc / sys / vm / overcommit_memory ). Com a confirmação excessiva, a chamada parafork()
sempre seria bem-sucedida e, como o processo filho não vai realmente usar essa cópia da memória, tudo está bem. Obviamente, é possível que, com a supercomprometimento, seus processos realmente tentem usar mais memória do que a disponível e sejam mortos pelo kernel. Se isso é apropriado depende dos outros usos da máquina. Máquinas de missão crítica provavelmente não devem arriscar que o assassino de falta de memória fique louco. Mas um servidor de desenvolvimento interno que possa permitir algum tempo de inatividade seria um bom local para permitir a supercomprometimento.Altere a JVM para não usar
fork()
+,exec()
mas para usarposix_spawn()
quando disponível. Esta é a solução solicitada no relatório de bug da JVM acima e mencionada na lista de discussão SCons. Também é implementado em java_posix_spawn .Estou tentando descobrir se essa correção chegou ao JDK7. Caso contrário, pergunto-me se o pessoal da Jenkins estaria interessado em uma solução alternativa, como java_posix_spawn. Parece ter havido tentativas de integrar isso ao Apache commons-exec .
Programmieraffe, não tenho 100% de certeza, mas seu link sugere que a correção está no JDK7 e JDK6 1.6.0_23 e posterior. Para o registro, eu estava executando o OpenJDK 1.6.0_18.
Consulte /programming/1124771/how-to-solve-java-io-ioexception-error-12-cannot-allocate-memory-calling-run
fonte
Observe a mensagem de exceção:
Cannot run program "/usr/bin/env": java.io.IOException: error=12, Cannot allocate memory"
O processo Java está tentando bifurcar um novo processo para executar o comando,/usr/bin/env
mas o sistema operacional ficou sem recursos de memória para criar um novo processo. Isso não é o mesmo que a Java VM ficando sem memória, portanto, nenhuma quantidade de mexer nos sinalizadores -Xmx o corrigirá. Você precisará monitorar seus recursos de memória enquanto executa sua compilação. Aumentar o espaço de troca provavelmente resolverá seu problema.fonte
É provável que ANT_OPTS sejam substituídos por Jenkins. Você também pode definir as opções diretamente no seu arquivo de construção, para poder controlar a alocação de memória independentemente do ambiente (shell, Jenkins, ...). No seu arquivo de construção (exemplo:
fonte