Jenkins未能为一项工作启动32位JVM

时间:2014-04-03 15:51:45

标签: java jenkins jvm

我正在运行Jenkins 1.557。我有一份工作需要使用32位版本的JDK 1.6_u45构建。我在我的作业的JDK设置中正确配置了该版本。但是,当我尝试运行该作业时,我收到以下错误。

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

如果我将作业的JDK设置切换为64位版本,则可以创建JVM并且它正常运行。服务器有8GB的RAM可用,我甚至试图传入JAVA_OPTS = -Xms512m -Xmx1024m&的字符串参数。 ANT_OPTS = -Xms512m -Xmx1024m到构建,但无济于事。

请注意,Could not reserve enough space for object heap的副本。如果我尝试在常规命令行上构建项目(Windows环境变量JAVA_HOME指向与Jenkins尝试相同的32位JDK安装),则项目构建。这似乎是詹金斯特有的问题。

我的猜测是在Jenkins(或一些隐藏的Jenkins配置文件)中的某个地方,JVM堆大小设置得太大而不适用于32位JVM,但我似乎无法确定设置的位置。我已经检查了JENKINS_HOME中的jenkins.xml,但是没有在arguments标签中设置堆大小。

1 个答案:

答案 0 :(得分:3)

答案

尝试使用较低的最大堆(-Xmx)值,例如-Xmx900m或-Xmx800m,看看是否可以解决问题。 根据我的经验,Jenkins尊重您的ANT_OPTS环境变量并且不会弄乱它。我使用Jenkins Freestyle Jobs亲自推出Ant,我总是设置ANT_OPTS,MAVEN_OPTS,......与Jenkins分开,它从未改变任何东西。制作

更好的是,从一个更低的值开始,比如-Xmx512m(我会使用ANT_OPTS,Ant使用它而不用打扰JAVA_OPTS)。如果它仍然无法初始化,那么,也许我会接受Jenkins正在做的事情。如果没有,那就是你的答案。

在根目录中,我认为这与您链接的重复问题是同一个问题,它只是在更有限的情况下重现。更多细节如下。

背景

就在昨天,在同事的机器上,我看到-Xmx1024m在标准命令窗口中失败,同时使用32位Java消息。仅仅因为它在一种情况下起作用并不意味着它总会有效。

在Windows上,每32位进程2GB的最大地址空间严重限制了您可以在Java中设置的最大堆大小,因为Java要求在一个连续的块中分配整个对象堆。特别是在使用ASLR(地址空间布局随机化)的Windows的现代版本中,您无法保证32位进程的大堆大小...甚至1024m有时可能太大,因为在Java中堆必须是连续的。画出从0到2GB的水平线,然后是[1GB]块,占据宽度的50%。现在将50个随机DLL插入到随机位置的2GB水平线中...现在尝试适合您的[1GB]块而不会点击。

不确切,这是我的穷人的地址空间图:

0 [________________________________________] 2GB
    _ is unallocated, available, | is occupied
Now with DLLs:
0 [__|_______|___________________|___|_____] 2GB
You need to fit this (including edges) into that address space:
[__________________]
Maybe it barely squeeks in...now let's add one more blip
0 [__|_______|_____________|_____|___|_____] 2GB
              [__________________]
Suddenly it won't fit. 

Jenkins可能会加载一个额外的DLL,它会使您的地址空间稍微分散一些,以便在Jenkins下1024m失败,但不会在独立窗口中失败。由于你的目标是在Jenkins下运行它,除了减少最大堆大小之外我没有看到明确的解决方案,因为你的目标是运行32位构建。在Windows XP时代,通常让-Xmx1300m左右工作,但显然甚至-Xmx1024m在Windows 7和Windows 8上都是一个延伸(在某些情况下,无论如何)。看起来最可能的情况是......你试图将堆设置得太大而不是32位。

验证

如果这确实不是问题,或者您不相信我,您可以验证您的64位版本的构建实际使用的Java内存设置(即因为它必须实际开始看到设置正在运行)。由于你的其他版本甚至无法启动,我不确定你可以在那里使用这种方法。无论Jenkins是否正在做某事,无论你是告诉你的工作是使用32位JDK还是64位JDK,如果它正在读取ANT_OPTS,它应该是从两个版本的环境变量获得相同的最终结果-Xmx值(工作的那个(64位)和失败的那个。您可以使用JDK附带的实用程序来执行此操作,称为jconsole。从JDK安装的bin目录中运行“jconsole”。或者,如果PATH中有%JAVA_HOME%\ bin,则应该能够直接启动jconsole。

这将启动一个图形客户端,允许您从其中运行JVM的任何进程ID(PID)中进行选择,在大多数情况下,此列表应该非常短。选择您的Ant进程并连接到它。切换到VM Information选项卡,您将看到JVM正在使用的堆设置和其他VM参数。

您将看到“VM Arguments”部分,其中应包括您的-Xms和-Xmx设置,以及“最大堆大小”,它可能以千字节为单位显示。

奖励知识,但由于您已经说过Java 6,因此没有直接相关。如果这是Java 7或更高版本,您可以使用:

jcmd

获取PID,然后:

jcmd <PID> VM.arguments

使用您指定的PID查看Java进程的VM参数。 jcmd being another utility that comes with the JDK。至少对我来说,这会显示原始字节值,因此您需要翻译。 (它不会显示-Xmx1024m它会显示-XX:MaxHeapSize = 1073741824)