如何指定 JVM 最大堆大小“-Xmx”以在 SBT 中运行具有“运行”操作的应用程序?

Posted

技术标签:

【中文标题】如何指定 JVM 最大堆大小“-Xmx”以在 SBT 中运行具有“运行”操作的应用程序?【英文标题】:How to specify JVM maximum heap size "-Xmx" for running an application with "run" action in SBT? 【发布时间】:2011-04-21 14:20:09 【问题描述】:

我的应用程序执行大型数据数组处理,并且需要比 JVM 默认提供的更多内存。我知道在 Java 中它是由“-Xmx”选项指定的。如何设置 SBT 以使用特定的“-Xmx”值来运行具有“运行”操作的应用程序?

【问题讨论】:

【参考方案1】:

对于分叉进程,您应该查看 Build.scala

要修改分叉进程的 java 选项,您需要在 Build.scala(或您为构建命名的任何名称)中指定它们,如下所示:

val buildSettings = Defaults.defaultSettings ++ Seq(
   //…
   javaOptions += "-Xmx1G",
   //…
)

这将为您提供正确的选项,而无需全局修改 JAVA_OPTS,并且它将自定义 JAVA_OPTS 放入 sbt generated start-script

对于 非分叉 进程,最方便的是通过 sbtoptssbtconfig 设置配置,具体取决于您的 sbt 版本。

自 sbt 0.13.6 .sbtconfig is deprecated.修改/usr/local/etc/sbtopts 如下:

-J-Xms512M
-J-Xmx3536M
-J-Xss1M
-J-XX:+CMSClassUnloadingEnabled
-J-XX:+UseConcMarkSweepGC
-J-XX:MaxPermSize=724M
-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

您还可以使用与/usr/local/etc/sbtopts 文件中相同的语法在您的 SBT 项目的根目录中创建一个.sbtopts 文件。这使得项目自成体系。

在 sbt 0.13.6 之前,您可以在 .sbtconfig 中为 非分叉 进程设置选项:

    检查 sbt 在哪里:

    $ which sbt
    /usr/local/bin/sbt
    

    看内容:

    $ cat /usr/local/bin/sbt
    #!/bin/sh
    test -f ~/.sbtconfig && . ~/.sbtconfig
    exec java $SBT_OPTS -jar /usr/local/Cellar/sbt/0.12.1/libexec/sbt-launch.jar "$@"
    

    设置正确的 jvm 选项以防止 OOM(常规和 PermGen):

    $ cat ~/.sbtconfig
    SBT_OPTS="-Xms512M -Xmx3536M -Xss1M 
     -XX:+CMSClassUnloadingEnabled 
     -XX:+UseConcMarkSweepGC -XX:MaxPermSize=724M"
    

如果您只想为当前运行的 sbt 设置 SBT_OPTS,您可以按照 Googol Shan 的建议使用 env SBT_OPTS=".." sbt。或者您可以使用 Sbt 12 中添加的选项:sbt -mem 2048。对于较长的选项列表,这会变得笨拙,但如果您有不同的项目有不同的需求,它可能会有所帮助。

请注意,CMSClassUnloadingEnabled 与 UseConcMarkSweepGC 一起有助于保持 PermGen 空间清洁,但根据您使用的框架,您可能会在 PermGen 上发生实际泄漏,这最终会强制重启。

【讨论】:

@iwein - javaOptions 没有更改 sbt 的默认堆空间。我签入了 jconsole,它只显示 -Xmx512M。即使我在 ~/.sbtconfig 中添加了 SBT_OPTS,我仍然会在 jconsole 中得到这个:-Xmx512M -Xms256M -Xmx1G -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC。你看到前面的 Xmx512 了吗?它有些如何不从 Build.scala 中选择 javaOptions。有什么指点吗? @Anand 也许在 0.13 中的工作方式略有不同?如果我遇到任何事情(可能需要一段时间),我会更新答案,如果你在此期间弄清楚,请告诉我。 @iwein 我刚刚在我的 Build.scala 中使用了以下内容并且它有效。 fork in run := true, javaOptions in run ++= Seq("-Xms256m", "-Xmx2048m", "-XX:+UseConcMarkSweepGC")。请参阅此帖子以获取答案***.com/questions/27372468/…。谢谢! 仅供参考,您还可以使用与 /usr/local/etc/sbtopts 文件中相同的语法在 SBT 项目的根目录中创建 .sbtopts 文件。这使您的项目自包含,在 CI 情况下非常方便。 在使用 0.13.9(可能是 0.13.6)的 Windows 上,文件是 C:\Program Files (x86)\sbt\conf\sbtconfig.txt。默认情况下,该文件中包含“-Xmx512M”,而此答案中没有显示-J。我可以通过 sbt 程序集发出关于 -XX:MaxPermSize 的警告这一事实来确认该文件正在被读取,并且当我更改该值时,警告显示的是我输入的值,而不是它最初显示的“256m”值。【参考方案2】:

在 sbt 版本 12 以后有一个选项:

$sbt -mem 2048 

【讨论】:

在 win 8.1 上,这个命令对我不起作用:Not a valid command: mem (similar: set)【参考方案3】:

如果你在 linux shell 上运行 sbt,你可以使用:

env JAVA_OPTS="-Xmx512m" sbt run

这是我运行我的 sbt 项目时常用的命令。

【讨论】:

非常感谢。一个很酷的命令知道。我从来不知道那个“env”,并且多次错过了这样的工具。 嗯,这对我不起作用!我需要上面的override def fork 解决方案。 (sbt 0.7.7) 您的 sbt 文件可能指定了它自己的 JAVA_OPTS,在这种情况下这些将被覆盖。然后,您可以直接修改您的 sbt 文件,以删除 -Xmx 标志或将其切换为所需的最大堆大小。 我认为不需要env【参考方案4】:

.sbtconfig 从 SBT 0.13.6 开始已弃用。相反,我通过以下方式在/usr/local/etc/sbtopts 中配置了这些选项:

-J-Xms512M
-J-Xmx3536M
-J-Xss1M
-J-XX:+CMSClassUnloadingEnabled
-J-XX:+UseConcMarkSweepGC
-J-XX:MaxPermSize=724M
-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

【讨论】:

-J-Xss1M 对于大case类来说有点低,4M似乎更安全。【参考方案5】:

试试这个:

class ForkRun(info: ProjectInfo) extends DefaultProject(info) 
    override def fork = Some(new ForkScalaRun 
        override def runJVMOptions = super.runJVMOptions ++ Seq("-Xmx512m")
        override def scalaJars = Seq(buildLibraryJar.asFile, buildCompilerJar.asFile)
    )

【讨论】:

这个已经过时了,现在可以使用javaOptions += "-Xmx1G" @iwein 我帖子的内容对你来说似乎很重要。 请注意,javaOptions 仅对分叉的 JVM 有效(请参阅 scala-sbt.org/0.13/docs/Forking.html 添加fork in run := ture 启用javaOptions @coanor 这个答案是针对古代版本的 sbt。在这个答案之下有一个排名更高的答案。此答案是提出问题时的正确答案。【参考方案6】:

我知道有一种方法。设置环境变量 JAVA_OPTS。

JAVA_OPTS='-Xmx512m'

我还没有找到将其作为命令参数的方法。

【讨论】:

【参考方案7】:

使用 JAVA_OPTS 进行环境变量设置。

使用 -J-X 选项来 sbt 单个选项,例如-J-Xmx2048 -J-XX:MaxPermSize=512

较新版本的 sbt 有一个“-mem”选项。

【讨论】:

【参考方案8】:

当我们看到通过 sbt 运行 Specs2 测试时抛出 java.lang.OutOfMemoryError 时,上面 @iwein 引用的 build.sbt 中的 javaOptions += "-XX:MaxPermSize=1024" 为我们工作。

【讨论】:

@UwePlonus 它确实回答了这个问题。【参考方案9】:

环境变量为_JAVA_OPTIONS,需要设置。 一旦你设置了 _JAVA_OPTIONS,当你 sbt 时,sbt 将使用 JAVA_OPTIONS 和值显示消息。

您也可以在 sbt 或 .scala 文件中设置 javaOption 例如

javaOptions += "-Xmx1G"

您可以从 sbt shell 运行 show javaOptions 来查看设置的值。

【讨论】:

【参考方案10】:
    javaOptions in Test += "-Xmx1G"

这会设置用于测试的 JVM 选项。也适用于 jvm 分叉 (fork in Test := true)。

【讨论】:

这个设置在build.sbt的哪里? 任何地方,如果你有一个单模块项目。在 SBT 中,定义的顺序通常无关紧要。如果您有多个模块,请在其中一些模块上指定,或者,如果需要,通过javaOptions in ThisBuild += "-Xmx1G"javaOptions in (ThisBuild, Test) += "-Xmx1G" 全局指定。【参考方案11】:

sbt 允许您列出在名为

的文件上运行项目所需的 JVM 选项

.jvmopts

在项目的根目录中。 然后添加你想要的 java 选项

cat .jvmopts
-Xms512M
-Xmx4096M
-Xss2M
-XX:MaxMetaspaceSize=1024M

它已经过测试并在 Windows 10 中运行 https://www.lagomframework.com/documentation/1.4.x/scala/JVMMemoryOnDev.html

【讨论】:

以上是关于如何指定 JVM 最大堆大小“-Xmx”以在 SBT 中运行具有“运行”操作的应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

Java 8 中默认的最大堆大小 (-Xmx) 是多少?

JVM优化

6个重要的JVM性能参数

jvm性能调优都做了啥

JVM参数

springboot最佳内存