【问题标题】:Ant: passing compilerarg into javacAnt:将编译器参数传递给 javac
【发布时间】:2011-05-07 07:05:03
【问题描述】:

我有可以编译的 ant 脚本:

            <javac srcdir="${test.src.dir}" destdir="${test.dist.dir}">
               ...  
               <compilerarg value="-Xlint:unchecked" />
            </javac>

我需要增加编译器的堆内存,所以我将以下参数放入compileargs

<compilerarg value="-Xlint:unchecked -Xms128m -Xmx512m" />

但我在控制台中收到错误:

[javac] javac: invalid flag: -Xms128m
[javac] Usage: javac <options> <source files>

为什么会这样?如何增加javac 使用的内存?

【问题讨论】:

  • 错误信息显示的值与提供的值不同 (32m/128m) 是否是复制/粘贴错误?
  • 也许您需要在单独的 元素中传递每个参数?
  • @ZeissS: 单独的&lt;compilerarg /&gt; 元素不幸导致同样的错误

标签: java memory ant heap-memory javac


【解决方案1】:

你试过Java任务下的&lt;jvmarg value="-Xmx512m" /&gt;吗?对于默认值,您可以使用 ANT_OPTS 环境变量。我发现了这个example,不是很有用,但有一个 build.xml。

为了增加 Javac 堆空间,我在谷歌搜索时发现了这个。

<javac fork="true"
       srcdir="${basedir}/src"
       destdir="${basedir}/build/classes"
       classpath="${project.classpath}"
       memoryinitialsize="256m"
       memorymaximumsize="256m">
</javac>

link 复制而来。将 fork 设置为 true 很重要。

【讨论】:

  • 抱歉,jvmargjavac 任务中无效:javac doesn't support the nested "jvmarg" element.
【解决方案2】:

我不认为这个问题真的与蚂蚁有关。如果您直接尝试javac -Xms128m -Xmx512m,您会看到相同的消息。

您需要使用-J 选项将标志直接传递给运行时系统。例如

-J-Xms128m -J-Xmx512m 而不是您的compilerarg 中的-Xms128m -Xmx512m

javac -X 用于将非标准选项传递给编译器。如果您运行命令javac -X,它将显示合法选项列表,其中包括您使用过的-Xlint。内存选项是底层 JVM 的设置,因此需要使用-J

替代方案

javac 任务有 memoryInitialSize(相当于 -Xms)和 memoryMaximumSize(相当于 -Xmx)选项,因此请尝试使用这些选项,而不是使用 compilerargs,例如

<javac srcdir="${test.src.dir}" destdir="${test.dist.dir}"
  memoryInitialSize="128m"
  memoryMaximumSize="512m">

【讨论】:

  • -J- 前缀产生相同的结果:[javac] javac: invalid flag: -J-Xms32m
  • 请尝试我添加到上述答案中的替代解决方案。
  • +1 - 替代方式有效,但我仍然想弄清楚为什么 -Xms32m-J-Xms32m 都不起作用
  • 我自己对此很感兴趣。 -J-Xms32m 在命令行运行 javac 时对我有用,但从 Ant 任务中运行时却不行。我已经尝试将 -verbose 与 Ant 一起使用,看看我是否可以发现正在执行的命令的差异,但什么也看不到。
  • @mikej 如所选答案中所述,我相信需要设置 fork="true" 才能将 -J 参数传递给新进程。
【解决方案3】:

默认情况下,&lt;javac&gt; 在 Ant 进程中运行。 Java 的一般限制是,一旦 JVM 进程启动,您就无法调整 JVM 进程的 XmsXmx。因此,您看到的错误消息是软件拒绝您违反此原则的尝试(使用无用、不友好的错误消息。)

但是,如果您在&lt;javac&gt; 标签上指定属性fork="true",您能够指定新的XmsXms。这是因为fork 指示Ant 启动一个新的JVM 子进程,在其中运行javac。因为 JVM 进程是新的,它给了 Ant 一个可接受的机会来为其指定 XmsXmx


你可以试试这样的:

<project name="project" default="all" basedir="[yourvalue]">
    <target name="all">
        <javac srcdir="[yourvalue]" destdir="[yourvalue]" fork="true">
            <!-- javac requires that -Xmx and -Xms be prefixed with -J -->
            <compilerarg line="-J-Xms128m -J-Xmx512m" />
        </javac>
    </target>
</project>

(注意我使用的是compilerarg line="" 而不是compilerarg value=""line 属性允许您指定多个以空格分隔的参数。value 属性用于传递单个参数。)


Ant 将等待分叉的&lt;javac&gt; 退出,这发生在javac 进程完成其工作(即编译)之后。 Ant 然后继续在它自己的原始 JVM 进程中运行构建脚本。 Ant 会检查分叉的javac 是失败还是成功,并根据这些信息采取通常的行动。


性能

fork javac 通常性能更高,而是简单地调整初始 Ant JVM 的相关内存设置。这通常(但不总是)是最佳选择,因为启动单独的 JVM 通常比简单地允许 javac 在进程内运行更慢并且占用更多内存。

如果您使用 Ant 提供的 ant.batant.sh 来启动 Ant,调整 Ant 的 XmsXmx 的简单方法是定义环境变量 ANT_OPTS 以包含您想要的参数。有很多方法可以设置环境变量,但你可以编辑ant.bat

set ANT_OPTS=-Xms128m -Xmx512m

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    相关资源
    最近更新 更多