81

I have noticed a strange behavior of my scala compiler. It occasionally throws an OutOfMemoryError when compiling a class. Here's the error message:

[info] Compiling 1 Scala source to /Users/gruetter/Workspaces/scala/helloscala/target/scala-2.9.0/test-classes...
java.lang.OutOfMemoryError: PermGen space
Error during sbt execution: java.lang.OutOfMemoryError: PermGen space

It only happens once in a while and the error is usually not thrown on the subsequent compile run. I use Scala 2.9.0 and compile via SBT.

Does anybody have a clue as to what might be the cause for this error? Thanks in advance for your insights.

KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
BumbleGee
  • 2,031
  • 3
  • 18
  • 18
  • The answers here also work for `java.lang.OutOfMemoryError: Metaspace` (the equivalent problem for Scala running on Java 8) if you replace `MaxPermSize` with `MaxMetaspaceSize`. – Brian McCutchon Jan 20 '17 at 05:01

9 Answers9

100

I use HomeBrew to install sbt on OS X. It supports a SBT_OPTS argument which can be put in ~/.sbtconfig file with export SBT_OPTS=-XX:MaxPermSize=256M.

michaelliu
  • 1,667
  • 2
  • 13
  • 13
  • 1
    Homebrew seems to be a very manageable package solution when developing with SBT. :) – crockpotveggies May 13 '13 at 20:46
  • the sbt brew install script sets memory max too small, get rid of the -Xmx512M in the java part - cat `which sbt` #!/bin/sh test -f ~/.sbtconfig && . ~/.sbtconfig exec java -Xmx512M ${SBT_OPTS} -jar /usr/local/Cellar/sbt/0.13.1/libexec/sbt-launch.jar "$@" – ski_squaw Apr 07 '14 at 21:44
  • there's a good SBT_OPTS setting in http://www.scala-sbt.org/release/docs/Getting-Started/Setup.html – ski_squaw Apr 07 '14 at 21:45
  • worked for me on windows set SBT_OPTS=-XX:MaxPermSize=512M – Alex Punnen Aug 09 '16 at 14:37
  • `Use of ~/.sbtconfig is deprecated, please migrate global settings to /usr/local/etc/sbtopts`, `Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256M; support was removed in 8.0` – Narfanator Nov 12 '18 at 19:34
47

The cause for OutOfMemoryError: PermGen space is that it doesn't have enough permanent generation space :) If you are using Oracle JVM, you need to add the -XX:MaxPermSize=256M (or some other amount of space) argument to your sbt script. For other JVMs, look at their documentation.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • 1
    Thanks Alexey. I've already used the -Xmx512M option. I think that should have the same effect, right? I've added the -XX:MaxPermSize parameter nonetheless and see if the error persists. – BumbleGee Nov 30 '11 at 21:17
  • 3
    @BumbleGee No, memory added by `-Xmx` can't be used for PermGen. – Alexey Romanov Dec 01 '11 at 05:36
  • Thanks for clarifying that, Alex. – BumbleGee Dec 01 '11 at 08:40
  • 6
    It looks like a memory leak in SBT as the program compiles and runs sucessfully for about 3-5 times before throwing the exception which is fixed by SBT restart. – Ivan Feb 21 '13 at 23:07
  • 4
    For the current version of `sbt` you need `-J-XX:MaxPermSize=256M` instead of `-XX:MaxPermSize=256M`. Tvaroh's answer is more accurate and complete, plus it doesn't make fun of the question. – Daniel Darabos Aug 14 '15 at 11:49
  • It sounds like there may be a memory leak in either sbt or your application. Wouldn't increasing permgen space only postpone the problem, not solve it? – Dan Li Jun 19 '16 at 23:24
38

I assumed you're using sbt 0.13.6 or higher. Create .sbtopts file in your sbt project's root with the following content:

-J-Xmx4G
-J-XX:MaxMetaspaceSize=1G
-J-XX:MaxPermSize=1G
-J-XX:+CMSClassUnloadingEnabled

MaxMetaspaceSize is for Java 8 whereas MaxPermSize is for Java 7. They are critical to prevent out of memory errors related either to permgen or metaspace exhaustion. Of course, consider adapting flag values or adding any other flags required.

More details and alternative approaches can be found in this blog post.

lev
  • 3,986
  • 4
  • 33
  • 46
Tvaroh
  • 6,645
  • 4
  • 51
  • 55
  • Great. You can also put these options in your global configuration file; for me it's `/usr/local/etc/sbtopts` (for sbt installed with Homebrew on Mac). – Brian McCutchon Jan 20 '17 at 06:00
6

I had this issue, played around with it for 10 minutes looking at sites trying to change the memory size.

Turns out i resolved it by,

user-profile$ sbt

Then,

sbt-project-name 0.1> clean

This cleared it up for me.

Alex Stewart
  • 730
  • 3
  • 12
  • 30
5

It looks like a memory leak in SBT for me as in my case the program compiles and runs successfully for about 3-5 times before hitting the exception which is fixed by SBT restart.

The most adequate solution indeed seems to be -XX:MaxPermSize= JVM parameter as Alexey Romanov suggests or to restart SBT periodically if it helps.

But there is another interesting way: try switching to Java 8. AFAIK it doesn't use PermGen any more and is probably immune to this exception this way.

I still hope SBT authors will address this issue in future versions.

Ivan
  • 63,011
  • 101
  • 250
  • 382
  • So Java 8 uses a different memory system? – Adrian Apr 03 '13 at 20:18
  • In J8 the perm gen is just rolled into the memory heap spaces. – sksamuel Jul 27 '13 at 21:26
  • With Java 8 SBT fails to compile, at least on my Mac. I have to downgrade to Java 7. – Siyuan Ren May 01 '14 at 08:20
  • Perhaps you are doing something wrong, @C.R. As far as I can remember I have tried it with Java 8 on Linux that time (when it was in deep beta) with no visible problems ans am using it with Java 8 on Windows right now. Perhaps you could show us the compiler error message you get? – Ivan May 01 '14 at 20:04
  • Thanks for the offer to help, but I decided not to go through the complicated process again. I'll stick to Java 7 for the time being. – Siyuan Ren May 02 '14 at 08:52
  • Nope, I get a Metaspace OutOfMemoryError with Java 8, which is basically the same thing. The `-XX:MaxMetaspaceSize=256M` option fixed this. – Brian McCutchon Jan 20 '17 at 05:19
3

I am building with the Jenkins sbt plugin and had the same problems. They were resolved after copying the SBT_OPTS from the sbt file to the Jenkins job config's JVM flags.

niebo
  • 41
  • 2
3

Originally using a command like:

java -jar /path/to/sbt-launch.jar test

I got first OutOfMemoryError: PermGen space which I solved using -XX:MaxPermSize, and then OutOfMemoryError: Java heap space, to which -Xmx was the remedy.

So in my case, a command like this worked:

java -XX:MaxPermSize=256M -Xmx2048M -jar /path/to/sbt-launch.jar test
Jonik
  • 80,077
  • 70
  • 264
  • 372
0

change following code block in sbt.sh file and save its working fine.

get_mem_opts () {
  local mem=${1:-1536}
  local perm=$(( $mem / 4 ))
  (( $perm > 256 )) || perm=1024 //256 to 1024
  (( $perm < 1024 )) || perm=2048 // 1024 to 2048
  local codecache=$(( $perm / 2 ))

  echo "-Xms${mem}m -Xmx${mem}m -XX:MaxPermSize=${perm}m -XX:ReservedCodeCacheSize=${codecache}m"
}

or

using terminal to export sbt config

export SBT_OPTS="-XX:+CMSClassUnloadingEnabled -XX:PermSize=1024M -XX:MaxPermSize=2048M"
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
0

You can also add a .jvmopts file in the root folder of your project, and write inside the file the following:

-Xms1g
-Xmx4g
Vitaly Olegovitch
  • 3,509
  • 6
  • 33
  • 49