100

I am using SBT 0.12.0. I have read other answers on stack overflow and followed them, however none of them helps, for example:

  • create ForkRun class - I have not observed any forked process during my usage of sbt
  • set environment variable JAVA_OPTS - it is set but sbt's process command line does not seem to use it at all.
  • sbt -J-Xmx2G appends the parameter to sbt process command line, however the old value -Xmx1536m is used by sbt instead of the appended parameter.

Am I missing something? How do I set heap size for sbt 0.12, when doing both testing and run?

spydon
  • 9,372
  • 6
  • 33
  • 63
  • 12
    Have you tried `mem` parameter when you starting sbt? (e.g. `sbt -mem2000`) – om-nom-nom Mar 07 '13 at 20:23
  • 2
    You might have a typo, it should be JAVA_OPTS not JAVA_OPS – Noah Mar 07 '13 at 20:57
  • Check out my answer to a duplicate of this question. http://stackoverflow.com/questions/3868863/how-to-specify-jvm-maximum-heap-size-xmx-for-running-an-application-with-run/14561346#14561346 the marked answer there is wrong, but mine works (sometimes you need to check comments/votes too :) – iwein Oct 09 '13 at 08:17

12 Answers12

109

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

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Noah
  • 13,821
  • 4
  • 36
  • 45
  • 1
    Thank you. It indeed changes sbt process command line as expected, however the old `-Xmx1546m` still exists in the command line and max heap size is still capped at 1.5 GB, as shown in visualvm. –  Mar 07 '13 at 21:56
  • 1
    any way to set this environment setting in the SBT config that's source-controlled? – Kevin Meredith Jan 16 '15 at 14:40
  • Take a look at scalaz source, they have a bash file called sbt that loads everything they need aka is environment specific https://github.com/scalaz/scalaz/blob/series/7.2.x/sbt – Noah Jan 16 '15 at 15:00
  • 4
    I get a warning: `Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=4G; support was removed in 8.0` – samthebest Mar 04 '15 at 17:29
  • 2
    @samthebest Perm Gen was basically removed in Java 8 so it's not necessary to include this. – Noah Mar 04 '15 at 20:27
  • why did you add timezone=GMT? – lyomi Jun 22 '15 at 12:00
  • This is what I use for my profile and we run everything in GMT regardless of physical location. – Noah Jun 22 '15 at 13:22
  • I added `export SBT_OPTS="-Xmx4G -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -Xss2M -XX:MaxPermSize=512M"` to my `~/.bash_profile; . ~/.bash_profile`, but I'm getting an `Out of Memory: heap space` error upon compilation: `java.lang.OutOfMemoryError: Java heap space` – Kevin Meredith Aug 20 '15 at 03:38
73

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
Synesso
  • 37,610
  • 35
  • 136
  • 207
  • 6
    This seems to also work well for windows, instead of having to mess around with env variables (the file is under c:\program files\sbt\confs). – Luciano Sep 24 '15 at 11:27
  • 2
    In Linux it's in `/etc/sbt-launcher-packaging`. – Robin Green Oct 23 '16 at 13:36
  • 1
    In Ubuntu Artful, I found it in `/etc/sbt/sbtopts` – Synesso Feb 15 '18 at 01:34
  • 1
    This solution will make the JVM preallocate all 2GB memory. If you use `SBT_OPTS=-Xmx2G sbt` to start SBT, it will grow the heap as needed up to a maximum of 2GB. – mgd Mar 27 '20 at 08:13
  • Have a look at @mike s solution above: https://stackoverflow.com/a/55706960/1199564 – mgd Mar 27 '20 at 08:19
47

"sbt -mem 23000 run" works for me.

GBY
  • 1,090
  • 1
  • 10
  • 13
22

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

16

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

Then if you want to check that you have set correctly run sbt -verbose

samthebest
  • 30,803
  • 25
  • 102
  • 142
mike
  • 1,956
  • 16
  • 22
15

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 %*
choy
  • 416
  • 1
  • 4
  • 8
11

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

Adrian Rodriguez
  • 3,232
  • 2
  • 24
  • 34
  • 2
    yes. This is what I have in $HOME/.sbtconfig. export SBT_OPTS="-XX:MaxPermSize=512M -Xmx2G -Xms64M" and when i start sbt, I do a ps aux and it displays /usr/bin/java -Xmx512M -XX:MaxPermSize=512M -Xmx2G -Xms64M -jar /usr/local/Cellar/sbt/0.13.0/libexec/sbt-launch.jar – Adrian Rodriguez Mar 20 '14 at 01:26
  • However, I just saw the answer below and perhaps that launcher is for another type of setup. My setup is specific to Mac using the homebrew package. – Adrian Rodriguez Mar 20 '14 at 01:31
  • 2
    Homebrew SBT now requires the heap size to be configured with `-mem` parameter in `/usr/local/etc/sbtopts` – Synesso Mar 16 '15 at 00:43
7

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
sungiant
  • 3,152
  • 5
  • 32
  • 49
7

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.

Jarekczek
  • 7,456
  • 3
  • 46
  • 66
  • 1
    Note: this `sbt\conf` is placed not in the user directory, but in the Program Files folder, like `C:\Program Files (x86)\sbt\conf`. – Suma Nov 29 '19 at 09:49
2

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

Cassio
  • 1,347
  • 13
  • 15
0

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.

0

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!

NickNgn
  • 122
  • 2
  • 8