Làm thế nào để ngăn chặn java.lang.OutOfMemoryError: PermGen space at Scala compilation?


79

Tôi đã nhận thấy một hành vi kỳ lạ của trình biên dịch scala của mình. Nó thỉnh thoảng ném ra OutOfMemoryError khi biên dịch một lớp. Đây là thông báo lỗi:

[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

Nó chỉ xảy ra một lần và lỗi thường không xảy ra trong lần chạy biên dịch tiếp theo. Tôi sử dụng Scala 2.9.0 và biên dịch qua SBT.

Có ai có manh mối về những gì có thể là nguyên nhân cho lỗi này? Cảm ơn trước cho những hiểu biết của bạn.


Các câu trả lời ở đây cũng hoạt động cho java.lang.OutOfMemoryError: Metaspace(vấn đề tương đương với Scala chạy trên Java 8) nếu bạn thay thế MaxPermSizebằng MaxMetaspaceSize.
Brian McCutchon

Câu trả lời:


46

Nguyên nhân OutOfMemoryError: PermGen spacelà do nó không có đủ không gian tạo vĩnh viễn :) Nếu bạn đang sử dụng Oracle JVM, bạn cần thêm đối số -XX:MaxPermSize=256M(hoặc một số dung lượng khác) vào sbttập lệnh của mình . Đối với các JVM khác, hãy xem tài liệu của họ.


1
Cảm ơn Alexey. Tôi đã sử dụng tùy chọn -Xmx512M. Tôi nghĩ rằng điều đó sẽ có tác dụng tương tự, phải không? Tuy nhiên, tôi đã thêm thông số -XX: MaxPermSize và xem lỗi có còn không.
BumbleGee

3
@BumbleGee Không, -Xmxkhông thể sử dụng bộ nhớ được thêm bởi PermGen.
Alexey Romanov

Cảm ơn vì đã làm rõ điều đó, Alex.
BumbleGee

6
Có vẻ như rò rỉ bộ nhớ trong SBT khi chương trình biên dịch và chạy thành công trong khoảng 3-5 lần trước khi ném ngoại lệ được khắc phục bằng cách khởi động lại SBT.
Ivan

4
Đối với phiên bản hiện tại của sbtbạn cần -J-XX:MaxPermSize=256Mthay vì -XX:MaxPermSize=256M. Câu trả lời của Tvaroh chính xác và đầy đủ hơn, cộng với việc nó không làm cho câu hỏi trở nên thú vị.
Daniel Darabos

99

Tôi sử dụng HomeBrew để cài đặt sbt trên OS X. Nó hỗ trợ một SBT_OPTSđối số có thể được đưa vào ~/.sbtconfigtệp export SBT_OPTS=-XX:MaxPermSize=256M.


1
Homebrew dường như là một giải pháp trọn gói rất dễ quản lý khi phát triển với SBT. :)
crockpotveggies

tập lệnh cài đặt sbt brew đặt bộ nhớ tối đa quá nhỏ, hãy loại bỏ -Xmx512M trong phần java - cat which sbt#! / bin / sh test -f ~ / .sbtconfig &&. ~ / .sbtconfig executive java -Xmx512M $ {SBT_OPTS} -jar /usr/local/Cellar/sbt/0.13.1/libexec/sbt-launch.jar "$ @"
ski_squaw

có một cài đặt SBT_OPTS tốt trong scala-sbt.org/release/docs/Getting-Started/Setup.html
ski_squaw,

đã làm việc cho tôi trên windows đặt SBT_OPTS = -XX: MaxPermSize = 512M
Alex Punnen

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

36

Tôi cho rằng bạn đang sử dụng SBT 0.13.6 hoặc cao hơn. Tạo .sbtoptstệp trong thư mục gốc của dự án sbt của bạn với nội dung sau:

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

MaxMetaspaceSizelà dành cho Java 8 trong khi đó MaxPermSizelà dành cho Java 7. Họ rất quan trọng để ngăn chặn ra lỗi bộ nhớ liên quan đến một trong hai để PermGen hoặc metaspace kiệt sức. Tất nhiên, hãy xem xét việc điều chỉnh các giá trị cờ hoặc thêm bất kỳ cờ nào khác được yêu cầu.

Có thể tìm thấy thêm chi tiết và các phương pháp tiếp cận thay thế trong bài đăng trên blog này .


Tuyệt quá. Bạn cũng có thể đưa các tùy chọn này vào tệp cấu hình chung của mình; đối với tôi đó là /usr/local/etc/sbtopts(đối với sbt được cài đặt bằng Homebrew trên Mac).
Brian McCutchon

5

Tôi đã gặp sự cố này, đã xử lý nó trong 10 phút khi xem các trang web đang cố gắng thay đổi kích thước bộ nhớ.

Hóa ra tôi đã giải quyết nó bằng cách,

user-profile$ sbt

Sau đó,

sbt-project-name 0.1> clean

Điều này đã giải tỏa nó cho tôi.


4

Đối với tôi, có vẻ như rò rỉ bộ nhớ trong SBT như trong trường hợp của tôi, chương trình biên dịch và chạy thành công trong khoảng 3-5 lần trước khi chạm vào ngoại lệ được khắc phục bằng khởi động lại SBT.

Giải pháp thích hợp nhất thực sự có vẻ là -XX:MaxPermSize=tham số JVM như Alexey Romanov đề xuất hoặc khởi động lại SBT định kỳ nếu nó hữu ích.

Nhưng có một cách thú vị khác: hãy thử chuyển sang Java 8 . AFAIK nó không sử dụng PermGen nữa và có thể miễn nhiễm với ngoại lệ này theo cách này.

Tôi vẫn hy vọng các tác giả SBT sẽ giải quyết vấn đề này trong các phiên bản sau.


Vậy Java 8 sử dụng một hệ thống bộ nhớ khác?
Adrian

Trong J8, gen perm chỉ được cuộn vào các không gian heap bộ nhớ.
sksamuel

Với Java 8 SBT không biên dịch được, ít nhất là trên máy Mac của tôi. Tôi phải hạ cấp xuống Java 7.
Siyuan Ren

Có lẽ bạn đang làm sai điều gì đó, @CR Theo như tôi có thể nhớ, tôi đã thử nó với Java 8 trên Linux vào thời điểm đó (khi nó đang ở phiên bản beta sâu) mà không có vấn đề gì rõ ràng. Hiện tại, tôi đang sử dụng nó với Java 8 trên Windows. Có lẽ bạn có thể cho chúng tôi thấy thông báo lỗi trình biên dịch mà bạn nhận được?
Ivan

Cảm ơn lời đề nghị giúp đỡ, nhưng tôi quyết định không thực hiện lại quy trình phức tạp nữa. Tôi sẽ gắn bó với Java 7 trong thời gian này.
Siyuan Ren

2

Tôi đang xây dựng với plugin Jenkins sbt và gặp vấn đề tương tự. Chúng đã được giải quyết sau khi sao chép SBT_OPTS từ tệp sbt sang cờ JVM của cấu hình công việc Jenkins.


2

Ban đầu sử dụng một lệnh như:

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

Đầu tiên tôi nhận được không gian OutOfMemoryError: PermGen mà tôi đã giải quyết bằng cách sử dụng -XX:MaxPermSize, và sau đó là OutOfMemoryError: không gian heap Java , đó -Xmxlà cách khắc phục.

Vì vậy, trong trường hợp của tôi, một lệnh như thế này đã hoạt động:

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

0

thay đổi khối mã sau trong tệp sbt.sh và lưu nó đang hoạt động tốt.

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

hoặc là

sử dụng thiết bị đầu cuối để xuất cấu hình sbt

export SBT_OPTS="-XX:+CMSClassUnloadingEnabled -XX:PermSize=1024M -XX:MaxPermSize=2048M"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.