Jenkins CI-无法分配内存


9

我在本地计算机上的ubuntu 10.4(具有vmware融合)上成功测试了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
  • 内存:1GB /动态2GB

我的问题:-1GB足以容纳Jenkins,还是必须升级服务器?-这个错误是由蚂蚁还是詹金斯引起的?

更新:我使用ant选项-Xmx128m -Xms128m运行它,但有时会再次发生该错误。(这吓到我了,因为我现在无法复制它:/)

帮助非常感谢!

干杯,马蒂亚斯


我通过设置詹金斯配置文件解决了这个问题:JENKINS_JAVA_OPTIONS =“-Djava.awt.headless = true -Xms500m -Xmx1000m”
herbertD

Answers:


10

Orien是正确的,它是由ProcessBuilder或Runtime.exec或其他JVM执行外部进程的方式(例如,另一个运行ant的JVM,git命令等)触发的fork()系统调用。

Jenkins邮件列表上有一些与此相关的帖子:无法运行程序“ git” ... error = 12,无法分配内存

SCons开发人员列表上有一个很好的问题描述:fork()+ exec()vs posix_spawn()

有一个长期存在的JVM Bug报告及其解决方案:在S10上使用posix_spawn而不是fork以避免交换耗尽。但是我不确定这是否真的像计划中所说的那样被纳入JDK7中。

总之,在类Unix的系统上,当一个进程(例如,JVM)需要启动另一个进程(例如,git)时,将进行系统调用,以fork()有效地复制当前进程及其所有内存(Linux等通过复制来优化此过程) -on-write,因此直到子级尝试对其进行写操作之前,实际上不会复制内存)。然后,复制进程进行另一个系统调用,exec()以启动另一个进程(例如git),此时,操作系统可能会丢弃所有从父进程复制的内存。如果父进程正在使用大量内存(如JVM进程倾向于这样做),则fork()即使操作系统确定子进程永远不会真正拥有足够的内存+交换来容纳两个副本,对的调用也可能会失败。使用该复制的内存。

有几种解决方案:

  • 向计算机添加更多的物理内存/ RAM。

  • 添加更多的交换空间以诱使它们fork()工作,即使对于任何东西都不严格需要交换空间。这是我选择的解决方案,因为添加交换文件非常容易,而且我不希望由于过量使用而导致进程被杀死。

  • 在Linux上,启用overcommit_memoryvm系统的选项(/ proc / sys / vm / overcommit_memory)。使用过量提交,对的调用fork()将始终成功,并且由于子进程实际上不会使用该内存副本,因此一切都很好。当然,通过过量使用,您的进程实际上可能会尝试使用比可用内存更多的内存,并被内核杀死。是否合适取决于机器的其他用途。关键任务计算机可能不应该冒着内存不足杀手运行的危险。但是可以承受一些停机时间的内部开发服务器将是启用过量使用的好地方。

  • 将JVM更改为不使用fork()+,exec()posix_spawn()在可用时使用。这是上面JVM错误报告中要求的解决方案,并且在SCons邮件列表中提到了该解决方案。它还在java_posix_spawn中实现。

    我试图找出该修补程序是否已纳入JDK7。如果没有,我想知道詹金斯人是否会对诸如java_posix_spawn之类的解决方案感兴趣。似乎已经尝试将其集成到Apache commons-exec中

    Programmieraffe,我不太确定,但您的链接确实表明该修复程序在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

附加问题:您会提出什么建议?过量使用内存设置?此致Matthias
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虚拟机(堆或堆栈之一),而不是主机系统。
mdpc

请原谅我的简短。我已经对其进行了更新,以描述为什么它不是JVM内存不足。
orien 2011年

0

Jenkins可能会覆盖ANT_OPTS。您还可以直接在构建文件中设置选项,以便可以独立于环境(shell,Jenkins等)控制内存分配。在您的构建文件中(例如:

<java fork="true" classname="..." >
    <jvmarg line="-Xms512M -Xmx512M" />
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.