106

My application does large data arrays processing and needs more memory than JVM gives by default. I know in Java it's specified by "-Xmx" option. How do I set SBT up to use particular "-Xmx" value to run an application with "run" action?

Ivan
  • 63,011
  • 101
  • 250
  • 382

11 Answers11

122

For forked processes you should look at Build.scala

To modify the java options for forked processes you need to specify them in the Build.scala (or whatever you've named your build) like this:

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

This will give you the proper options without modifying JAVA_OPTS globally, and it will put custom JAVA_OPTS in an sbt generated start-script

For non forked processes it's most convenient to set the config via sbtopts or sbtconfig depending on your sbt version.

Since sbt 0.13.6 .sbtconfig is deprecated. Modify /usr/local/etc/sbtopts along these lines:

-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

You can also create an .sbtopts file in the root of your SBT project using the same syntax as in the /usr/local/etc/sbtopts file. This makes the project self-contained.

Before sbt 0.13.6 you could set the options in .sbtconfig for non forked processes:

  1. Check where sbt is:

    $ which sbt
    /usr/local/bin/sbt
    
  2. Look at the contents:

    $ 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 "$@"
    
  3. Set the correct jvm options to prevent OOM (both regular and PermGen):

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

If you want to set SBT_OPTS only for the current run of sbt you can use env SBT_OPTS=".." sbt as suggested by Googol Shan. Or you can use the option added in Sbt 12: sbt -mem 2048. This gets unwieldy for longer lists of options, but it might help if you have different projects with different needs.

Note that CMSClassUnloadingEnabled in concert with UseConcMarkSweepGC helps keep the PermGen space clean, but depending on what frameworks you use you might have an actual leak on PermGen, which eventually forces a restart.

Waldemar Wosiński
  • 1,490
  • 17
  • 28
iwein
  • 25,788
  • 10
  • 70
  • 111
  • @iwein - The javaOptions did not change the default heapspace for sbt. I checked in jconsole and it just shows -Xmx512M. Even if I add the SBT_OPTS in ~/.sbtconfig, I still get this in jconsole: -Xmx512M -Xms256M -Xmx1G -XX:MaxPermSize=256M -XX:+UseConcMarkSweepGC. Do you see the Xmx512 up in the front? It some how doesn't pick the javaOptions from Build.scala. Any pointers? – Anand Dec 09 '14 at 06:02
  • @Anand perhaps things are working slightly differently in 0.13? I'll update the answer if I bump into anything (might take a while), let me know if you figure it out in the mean time. – iwein Dec 12 '14 at 21:25
  • @iwein I just used the following in my Build.scala and it worked. fork in run := true, javaOptions in run ++= Seq("-Xms256m", "-Xmx2048m", "-XX:+UseConcMarkSweepGC"). See this post for the answer http://stackoverflow.com/questions/27372468/sbt-specify-java-heap-size-in-build-scala/27373101#comment43198372_27373101. Thanks! – Anand Dec 15 '14 at 05:22
  • 3
    FYI you can also create a `.sbtopts` file in the root of your SBT project using the same syntax as in the `/usr/local/etc/sbtopts` file. This makes your project self-contained, which can be very handy in CI situations. – Age Mooij Jan 04 '16 at 09:01
  • 1
    On Windows using 0.13.9 (might be 0.13.6) the file is C:\Program Files (x86)\sbt\conf\sbtconfig.txt. By default the file had "-Xmx512M" in it without the -J shown in this answer. I can confirm that this file is being read by the fact that sbt assembly issues a warning regarding -XX:MaxPermSize and when I change that value the warning shows the value I entered and not the "256m" value it showed originally. – Night Owl Feb 03 '17 at 00:44
  • Can someone please provide information for inspecting these settings? What is the fastest find to find out if sbt actually picked those up? – agilesteel Jun 02 '17 at 06:33
  • I found them through the Java VisualVM but I'm sure there is a faster way, through SBT itself somehow. Is there? – agilesteel Jun 02 '17 at 06:39
  • Talking to myself here, but this is what I was looking for: -XshowSettings:vm – agilesteel Jun 26 '23 at 23:50
75

In sbt version 12 onwards there is an option for this:

$sbt -mem 2048 
JoshDM
  • 4,939
  • 7
  • 43
  • 72
Prashant Sharma
  • 1,067
  • 8
  • 14
46

If you run sbt on linux shell, you can use:

env JAVA_OPTS="-Xmx512m" sbt run

This is my usually used command to run my sbt project.

Googol Shan
  • 1,255
  • 9
  • 13
  • 1
    Thank you very much. A cool command to know. I never knew of that "env" and missed such a tool many times. – Ivan Nov 05 '10 at 04:44
  • 4
    Hmm, this didn't work for me! I needed the `override def fork` solution above. (sbt 0.7.7) – Scott Morrison Jul 05 '11 at 16:02
  • 2
    it is possible that your sbt file specifies its own JAVA_OPTS, in which case these will be overwritten. You can then just directly modify your sbt file, either to remove the -Xmx flag or to switch it to your desired maximum heap size. – nnythm Mar 01 '12 at 18:21
  • I don't think `env` is required – bbarker May 27 '21 at 17:52
24

.sbtconfig is deprecated starting with SBT 0.13.6. Instead, I configured these options in /usr/local/etc/sbtopts in the following way:

-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
omnomnom
  • 8,911
  • 4
  • 41
  • 50
17

Try this:

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)
    })
}
iwein
  • 25,788
  • 10
  • 70
  • 111
Arne
  • 7,921
  • 9
  • 48
  • 66
  • 54
    This is outdated, now you can use `javaOptions += "-Xmx1G"` – iwein Feb 12 '13 at 17:35
  • 1
    @iwein the content of my post seems to be very important to you. – Arne Nov 07 '15 at 01:51
  • 2
    Note that `javaOptions` only have effect for forked JVMs (see http://www.scala-sbt.org/0.13/docs/Forking.html) – Yar Nov 26 '15 at 15:50
  • 1
    Add `fork in run := ture` enables `javaOptions` – coanor Apr 10 '16 at 04:42
  • @coanor this answer is for an ancient version of sbt. There is an answer with much higher rankings just under this one. This answer was the correct answer at the time when the question was asked. – Arne Apr 10 '16 at 14:28
7

Use JAVA_OPTS for setting with environment variable.

Use -J-X options to sbt for individual options, e.g. -J-Xmx2048 -J-XX:MaxPermSize=512

Newer versions of sbt have a "-mem" option.

Brett
  • 5,690
  • 6
  • 36
  • 63
7

There's one way I know of. Set the environment variable JAVA_OPTS.

JAVA_OPTS='-Xmx512m'

I have not found a way to do this as a command parameter.

Synesso
  • 37,610
  • 35
  • 136
  • 207
5

The javaOptions += "-XX:MaxPermSize=1024" in our build.sbt as referenced by @iwein above worked for us when we were seeing a java.lang.OutOfMemoryError thrown while running Specs2 tests through sbt.

Pete Neisen
  • 131
  • 1
  • 5
3

The environment variable is _JAVA_OPTIONS, which needs to be set. Once you set _JAVA_OPTIONS, and when you sbt, sbt will show the message using JAVA_OPTIONS and the values.

Alternatively you could set javaOption in the sbt or .scala file e.g

javaOptions += "-Xmx1G"

From sbt shell you could run show javaOptions to see the values that are set.

2

sbt lets you list the JVM options you need to run your project on a file named

.jvmopts

in the root of your project. then add the java options that you want

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

it is tested and works in windows 10 https://www.lagomframework.com/documentation/1.4.x/scala/JVMMemoryOnDev.html

Ar maj
  • 1,974
  • 1
  • 16
  • 16
1
    javaOptions in Test += "-Xmx1G"

This sets the JVM options for tests. Works also with jvm forking (fork in Test := true).

VasiliNovikov
  • 9,681
  • 4
  • 44
  • 62
  • 1
    where is this set in the `build.sbt` ? – WestCoastProjects Jan 10 '17 at 23:05
  • Anywhere, if you have a 1-module project. The order of definitions does not generally matter in SBT. If you have multiple modules, specify this either on some of them or, if you want, globally via `javaOptions in ThisBuild += "-Xmx1G"` or `javaOptions in (ThisBuild, Test) += "-Xmx1G"` – VasiliNovikov Jan 11 '17 at 07:33