Как предотвратить java.lang.OutOfMemoryError: пространство PermGen при компиляции Scala?

Я заметил странное поведение моего компилятора scala. Иногда он генерирует ошибку OutOfMemoryError при компиляции класса. Вот сообщение об ошибке:

[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

Это происходит только время от времени, и ошибка обычно не выдается при следующем запуске компиляции. Я использую Scala 2.9.0 и компилирую через SBT.

Кто-нибудь знает, что может быть причиной этой ошибки? Заранее спасибо за ваши идеи.

9 ответов

Решение

Причина для OutOfMemoryError: PermGen space в том, что у него недостаточно места для постоянной генерации:) Если вы используете Oracle JVM, вам нужно добавить -XX:MaxPermSize=256M (или некоторый другой объем пространства) аргумент к вашему sbt скрипт. Для других JVM посмотрите их документацию.

Я использую HomeBrew для установки sbt на OS X. Он поддерживает SBT_OPTS аргумент, который можно поставить в ~/.sbtconfig файл с export SBT_OPTS=-XX:MaxPermSize=256M,

Я предположил, что вы используете SBT 0,13,6 или выше. Создайте .sbtopts файл в корне вашего проекта sbt со следующим содержимым:

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

MaxMetaspaceSize для Java 8, тогда как MaxPermSize для Java 7. Они имеют решающее значение для предотвращения ошибок нехватки памяти, связанных с исчерпанием permgen или metaspace. Конечно, рассмотрите возможность адаптации значений флагов или добавления любых других необходимых флагов.

Более подробную информацию и альтернативные подходы можно найти в этом блоге.

У меня была эта проблема, я поиграл с ней 10 минут, просматривая сайты, пытаясь изменить размер памяти.

Оказывается, я решил это,

user-profile$ sbt

Затем,

sbt-project-name 0.1> clean

Это прояснило это для меня.

Для меня это выглядит как утечка памяти в SBT, так как в моем случае программа компилируется и успешно работает примерно 3-5 раз, прежде чем выполнить исключение, которое исправлено при перезапуске SBT.

Наиболее адекватное решение действительно, кажется, -XX:MaxPermSize= Параметр JVM, как предлагает Алексей Романов, или периодически перезапускать SBT, если это поможет.

Но есть и другой интересный способ: попробуйте перейти на Java 8. AFAIK, он больше не использует PermGen и, вероятно, невосприимчив к этому исключению.

Я все еще надеюсь, что авторы SBT решат эту проблему в следующих версиях.

Первоначально с помощью такой команды:

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

Я получил первый OutOfMemoryError: пространство PermGen, которое я решил использовать -XX:MaxPermSize, а затем OutOfMemoryError: пространство кучи Java, к которому -Xmx было лекарство.

Так что в моем случае такая команда сработала:

java -XX:MaxPermSize=256M -Xmx2048M -jar /path/to/sbt-launch.jar test

Я строю с плагином Jenkins sbt и у меня были те же проблемы. Они были решены после копирования SBT_OPTS из файла sbt во флаги JVM конфигурации задания Jenkins.

Измените следующий блок кода в файле sbt.sh и сохраните его в порядке.

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"
}

или же

используя терминал для экспорта конфигурации sbt

export SBT_OPTS="-XX:+CMSClassUnloadingEnabled -XX:PermSize=1024M -XX:MaxPermSize=2048M"

Вы также можете добавить .jvmopts файл в корневой папке вашего проекта и напишите внутри файла следующее:

      -Xms1g
-Xmx4g
Другие вопросы по тегам