Jenkins CI – 不能分配内存

我在本地计算机上成功地testing了jenkins-ci,在Ubuntu 10.4上(与vmware融合)。 现在我想安装和使用它在我的虚拟服务器在hosteurope。 基本的安装没有问题,但现在我的生成项目有问题。

从存储库中拉出mercurial更新之后,ant被调用,并在我的生成项目中引发以下错误:

“Buildfile:/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-diiagnostics”贯穿始终,并且不会导致错误,但是当我尝试构build项目时仍然出现错误。

服务器详细信息: – http://www.hosteurope.de/produkt/Virtual-Server-Linux-L

  • Ubuntu 10.4 LTS
  • 内存:1GB /dynamic2GB

我的问题: – jenkins是1GB还是我必须升级服务器? – 这个错误是由ant还是jenkins造成的?

更新:我得到它运行ant选项-Xmx128m -Xms128m,但有时错误再次发生。 (这吓坏了我,因为我不能现在重现:/)

非常感谢!

干杯,马提亚斯

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

Jenkins邮件列表上有一些关于此的post: 无法运行程序“git”… error = 12,无法分配内存

在SCons开发列表中有一个很好的描述: fork()+ exec()vs posix_spawn()

有一个长期存在的JVM错误报告和解决scheme: 在S10上使用posix_spawn而不是fork,以避免交换耗尽 。 但是我不确定这是否真的将其转化为JDK7,正如评论所暗示的那样。

总而言之,在类Unix系统上,当一个进程(如JVM)需要启动另一个进程(例如git)时,系统调用fork()会有效地复制当前进程及其所有内存(Linux等)这与写入时复制,所以内存实际上不会被复制,直到孩子试图写入)。 重复的过程然后进行另一个系统调用exec()来启动另一个进程(例如git),此时从父进程复制内存的所有内容都可能被操作系统丢弃。 如果父进程正在使用大量内存(如JVM进程往往这样做),如果操作系统确定它没有足够的内存+交换来保存两个副本,则对fork()的调用可能会失败,即使subprocess将永远不会实际使用该复制的内存。

有几个解决scheme:

  • 添加更多物理内存/ RAM到机器。

  • 添加更多的交换空间来诱使fork()进入工作状态,即使交换空间不是严格需要的。 这是我select的解决scheme,因为添加一个交换文件相当简单,而且我不想忍受由于过度使用而导致进程死亡的可能性。

  • 在Linux上,启用overcommit_memory系统的overcommit_memory选项( / proc / sys / vm / overcommit_memory )。 对于overcommit,对fork()的调用总是成功的,而且由于subprocess实际上不会使用该内存副本,所以一切都很好。 当然,有可能过度使用,你的进程实际上会尝试使用比现有更多的内存,并被内核杀死。 这是否合适取决于机器的其他用途。 关键任务的机器应该不会冒险失控的杀手。 但是一个能够承受停机时间的内部开发服务器将是一个很好的启用overcommit的地方。

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

    我试图找出是否修复成JDK7。 如果没有,我不知道jenkins人是否会对java_posix_spawn等工作感兴趣。 似乎已经尝试将其整合到Apache commons-exec中 。

    Programmieraffe,我不是100%肯定的,但是你的链接确实表明修补程序在JDK7和JDK6 1.6.0_23及更高版本中。 为了logging,我正在运行OpenJDK 1.6.0_18。

请参阅https://stackoverflow.com/questions/1124771/how-to-solve-java-io-ioexception-error-12-cannot-allocate-memory-calling-run

Jenkins可能会重写ANT_OPTS。 您也可以直接在您的构build文件中设置选项,以便您可以独立于环境(shell,Jenkins,…)独立控制内存分配。 在您的构build文件(例如:

 <java fork="true" classname="..." > <jvmarg line="-Xms512M -Xmx512M" /> 

请注意exception消息: Cannot run program "/usr/bin/env": java.io.IOException: error=12, Cannot allocate memory" Java进程试图fork一个新进程来运行命令/usr/bin/env但是操作系统已经耗尽了内存资源来创build一个新的进程,这与Java虚拟机内存不足无关,所以没有用-Xmx标志来解决这个问题,你需要监视你的内存资源,同时运行你的构build。增加交换空间可能会解决你的问题。