4

我有一个 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()上面的调用中得知 Clover 在 Ant 使用的 JVM 中被反射调用。

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

ANT_OPTS被设定为-Xmx1024m -Xms512m

这并没有解决问题。(我从空中提取了这些数字,最大尺寸没有以任何方式计算。)

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

4

3 回答 3

2

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

无论如何,有一个很好的指导

在此处输入图像描述

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

于 2014-01-06T12:23:43.473 回答
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 指定的最大堆大小在老年代和新生代之间分开。

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

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
于 2014-01-13T05:14:34.540 回答
1

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

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

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

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

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

于 2014-01-10T12:30:53.797 回答