如何为 sbt 设置堆大小?

我正在使用 SBT 0.12.0。我读过其他关于堆栈溢出的答案,并跟随了它们,但没有一个有帮助,例如:

  • Create ForkRun class-我在使用 sbt 时没有观察到任何分叉过程
  • 设置环境变量 JAVA_OPTS-已经设置了,但 sbt 的 process 命令行似乎根本没有使用它。
  • sbt -J-Xmx2G将参数追加到 sbt 进程命令行,但 sbt 使用旧值 -Xmx1536m代替追加的参数。

我是否遗漏了什么? 在同时进行测试和 run时,如何为 sbt 0.12设置堆大小?

104177 次浏览

You need SBT_OPTS, here's what I use in my .bash_profile:

export SBT_OPTS="-Xmx1536M -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=2G -Xss2M  -Duser.timezone=GMT"

UPDATE: To get your 2G heap space you can use this:

export SBT_OPTS="-Xmx2G -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=2G -Xss2M  -Duser.timezone=GMT"

NOTE: SBT MUST BE LATEST VERSION

Older versions of sbt contain bugs that override these settings, use brew upgrade sbt for latest sbt for Mac (assuming brew install) (IDK for Linux). https://github.com/sbt/sbt/issues/2945#issuecomment-277490848

I have found the solution. No matter how you specify JVM heap size, it will never work because SBT executable already has it overridden.

There is a line in SBT executable which says:

. /usr/share/sbt/sbt-launch-lib.bash

So I edited the file:

  # run sbt
execRunner "$java_cmd" \
${SBT_OPTS:-$default_sbt_opts} \
-   $(get_mem_opts $sbt_mem) \
${java_opts} \
${java_args[@]} \
-jar "$sbt_jar" \
"${sbt_commands[@]}" \
"${residual_args[@]}"

Remove the - line.

Now when you run SBT, it will no longer override your JVM heap size settings. You can specify heap size settings using @Noan's answer.

Or alternatively:

sbt -J-Xmx4G -J-Xms4G

I was looking to solve a problem like this on Mac OS X with a homebrew install of SBT. If you installed SBT via homebrew, you're in the clear since the /usr/local/bin/sbt file looks like

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

This means that any settings you put in SBT_OPTS will stick (your -Xmx will take precedence). Furthermore, the first line of the script will execute any commands in ~/.sbtconfig if it exists so it may be a better place to put your SBT options if you are playing with them quite a bit. You won't have to source ~/.bash_profile every time you make a change to SBT_OPTS

"sbt -mem 23000 run" works for me.

As of March 2015, if you are using sbt on OSX with Homebrew then you should edit the file /usr/local/etc/sbtopts

e.g.

# set memory options
#
#-mem   <integer>
-mem 2048

On windows, for sbt 0.13.9.2, you need to set JAVA_OPTS to the jvm options you want.

> set JAVA_OPTS=-Xmx1G
> sbt assembly

The sbt.bat script loads its defaults from conf\sbtconfig.txt into CFG_OPTS but will use JAVA_OPTS instead if set.

Relevant excerpts from sbt.bat:

rem FIRST we load the config file of extra options.
set FN=%SBT_HOME%\..\conf\sbtconfig.txt
set CFG_OPTS=
FOR /F "tokens=* eol=# usebackq delims=" %%i IN ("%FN%") DO (
set DO_NOT_REUSE_ME=%%i
rem ZOMG (Part #2) WE use !! here to delay the expansion of
rem CFG_OPTS, otherwise it remains "" for this loop.
set CFG_OPTS=!CFG_OPTS! !DO_NOT_REUSE_ME!
)

. . . (skip) . . .

rem We use the value of the JAVA_OPTS environment variable if defined, rather than the config.
set _JAVA_OPTS=%JAVA_OPTS%
if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=%CFG_OPTS%
:run
"%_JAVACMD%" %_JAVA_OPTS% %SBT_OPTS% -cp "%SBT_HOME%sbt-launch.jar" xsbt.boot.Boot %*

If running sbt from PowerShell, set the SBT_OPTs environment variable, like so:

$env:SBT_OPTS="-Xms512M -Xmx1024M -Xss2M -XX:MaxMetaspaceSize=1024M"

Then run:

sbt

For SBT version 1.0.4 on Windows the default JVM settings come from sbt\conf\sbtconfig.txt file. Simply edit the values here. Change -Xmx512M to -Xmx2048M.

This is not the only source of JVM options for SBT. Others can be found by inspecting sbt.bat. A simple way to diagnose, where do the settings come from, is by commenting out this line in batch file: @echo off.

A quick way to do it is with a .jvmopts file in the root of your project (from the Lagom Framework documentation):

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

In my case, the configuration of my service was overwriting the environment variable SBT_OPTS and JAVA_OPTS. I was able to set the limits by setting in my build.sbt the following:

javaOptions in Universal ++= Seq(
"-J-Xms1g",
"-J-Xmx2g")

Reference: https://www.scala-sbt.org/sbt-native-packager/archetypes/java_app/customize.html

On windows, running SET SBT_OPTS="-XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=2G -Xmx2G -Xms1G" before sbt seems to be what solved it for me.

Reference: https://www.baeldung.com/scala/sbt-heap-size

I just changed export to SET.

If you're using Windows, you can easily set as environment variables:

enter image description here

Afterward, don't forget to restart your terminal prompt (CMD, Powershell,...) to refresh.

This does work for me!