OutOfMemoryError在从QuickBuild运行的Ant中创建三叶草快照

时间:2014-01-02 05:05:17

标签: ant clover quickbuild

我有一个QuickBuild服务器(5.0.14)。这是使用ant运行构建步骤。

Ant目标如下所示:

<target name="clover-snapshot" depends="with-clover">
  <clover-snapshot file="${clover.snapshot.file}"/>
</target>

我们正在使用Clover版本3.1.5。

此步骤失败,出现以下堆栈跟踪: -

java.lang.OutOfMemoryError: Java heap space
    at com.cenqua.clover.util.CloverBitSet.read(CloverBitSet.java:71)
    at com.cenqua.clover.PerTestRecordingTranscript.read(PerTestRecordingTranscript.java:45)
    at com.cenqua.clover.RecordingTranscripts.readSliceFromDisk(RecordingTranscripts.java:124)
    at com.cenqua.clover.RecordingTranscripts$FileRef.read(RecordingTranscripts.java:354)
    at com.cenqua.clover.CoverageDataCollator.collatePerTestRecordings(CoverageDataCollator.java:156)
    at com.cenqua.clover.CoverageDataCollator.loadCoverageData(CoverageDataCollator.java:68)
    at com.cenqua.clover.CloverDatabase.loadCoverageData(CloverDatabase.java:164)
    at com.cenqua.clover.CloverDatabase.loadCoverageData(CloverDatabase.java:159)
    at com.cenqua.clover.CloverDatabase.loadWithCoverage(CloverDatabase.java:283)
    at com.cenqua.clover.tasks.CloverSnapshotTask.cloverExecute(CloverSnapshotTask.java:51)
    at com.cenqua.clover.tasks.AbstractCloverTask.execute(AbstractCloverTask.java:55)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
    at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:392)
    at org.apache.tools.ant.Target.performTasks(Target.java:413)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
    at org.apache.tools.ant.Main.runBuild(Main.java:811)
    at org.apache.tools.ant.Main.startAnt(Main.java:217)
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

我从上面的invoke()调用中得到它,在Ant使用的JVM中反复调用Clover。

因此,我试图为Ant JVM分配更多的堆空间。我这样做是通过编辑QuickBuild中的构建步骤并指定以下环境变量: -

ANT_OPTS设置为-Xmx1024m -Xms512m

这还没有解决问题。 (我把这些数字从空中拨出,最大尺寸没有以任何方式计算。)

我的问题是,如何为Clover分配额外的堆空间以允许它在不耗尽内存的情况下执行。或者,我该怎么做才能确认这些设置?

3 个答案:

答案 0 :(得分:2)

看起来你做的一切都是正确的。 ANT_OPTS是解决此问题的正确方法。我使用了几乎相同的方法来解决类似的问题。你使用的是64位JVM吗?您是否看到实际分配了空间?

无论如何,有一个很好的instruction

enter image description here

我还建议使用VisualVM来验证JVM是否已正确创建并确定实际原因。

答案 1 :(得分:1)

有两种方法可以增加ant的内存大小:

  1. 在环境变量中设置ANT_OPTS属性的值。例如:
    set ANT_OPTS=-Xms256m -Xmx1024m -XX:MaxPermSize=120m

  2. 在ant Java目标中指定maxmeory属性。 例如:

  3. <target name="MergingHugeJars"> 
        <echo message="Merging jars ${InputJars} into ${OutputJar}"/>
        <java jvm="${JVM}" classname="com.krishna.test.MergeHugeJars" fork="true" failonerror="true" maxmemory="512m" > 
            <arg line="${OutputJar} ${InputJars}"/>
        </java>
    </target> 

    你可以摆弄第三行的maxmemory="512m"部分。

答案 2 :(得分:1)

您可以使用jstat附加到正在运行的java进程,并查看您的设置是否正在使用:

$ jstat -gccapacity 19726
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC      PGCMN    PGCMX     PGC       PC     YGC    FGC 
 42560.0 681984.0  42560.0 5312.0 5312.0  31936.0    85248.0  1363968.0    85248.0    85248.0  21248.0 169984.0  21248.0  21248.0      0     0

Xmx是NGCMX和OGCMX的组合。在英语中,通过-Xmx指定的最大堆大小在Old generation和New generation之间分配。

一个快速的小脚本,可以很好地格式化这些信息:

jcmd | grep -v JCmd | while read pid name; do echo -n "Xmx for $name "; jstat -gccapacity $pid | sed '1d' | awk '{ print $2 + $8 " MB" }'; done
Xmx for org.example.MyClass 2045952 MB