Как предотвратить 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