Maven Out of Memory Build Thất bại


88

Cho đến hôm nay, biên dịch maven của tôi không thành công.

[INFO] [ERROR] Unexpected
[INFO] java.lang.OutOfMemoryError: Java heap space
[INFO]  at java.util.Arrays.copyOfRange(Arrays.java:2694)
[INFO]  at java.lang.String.<init>(String.java:203)
[INFO]  at java.lang.String.substring(String.java:1877)

[LỖI] Hết bộ nhớ; để tăng dung lượng bộ nhớ, hãy sử dụng cờ -Xmx khi khởi động (java -Xmx128M ...)

Tính đến ngày hôm qua, tôi đã chạy thành công một biên dịch maven.

Tính đến hôm nay, tôi vừa tăng khối lượng của mình lên 3 GB . Ngoài ra, tôi chỉ thay đổi 2-3 dòng mã nhỏ, vì vậy tôi không hiểu lỗi 'hết bộ nhớ' này.

vagrant@dev:/vagrant/workspace$ echo $MAVEN_OPTS
-Xms1024m -Xmx3000m -Dmaven.surefire.debug=-Xmx3000m

CHỈNH SỬA: Tôi đã thử nhận xét của người đăng bằng cách thay đổi pom.xml của mô-đun bị lỗi của tôi. Nhưng tôi gặp cùng một lỗi xây dựng maven.

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.5</source>
            <target>1.5</target>
            <fork>true</fork>
            <meminitial>1024m</meminitial>
            <maxmem>2024m</maxmem>
       </configuration>
    </plugin>

1
Bạn có thể cung cấp thêm hệ thống ngăn xếp không? Tôi tò mò muốn biết điều gì có thể khiến quá trình khởi tạo Chuỗi hết bộ nhớ. Đặt kích thước heap trong MAVEN_OPTS nghe có vẻ giống như cách để thực hiện nhưng tôi đoán là ở đâu đó có một Chuỗi lớn đến mức nực cười mà bạn có thể không phân bổ đủ -Xmx.
Edward Samson

Câu trả lời:


136

Bạn đang nói về loại mô-đun 'web' nào? Nó có phải là một cuộc chiến tranh đơn giản và có cuộc chiến tranh kiểu đóng gói?

Nếu bạn không sử dụng bộ công cụ web của Google (GWT) thì bạn không cần cung cấp gwt.extraJvmArgs

Thay đổi quá trình biên dịch có thể không phải là ý tưởng tốt nhất, bởi vì nó bắt đầu một quá trình thứ hai bỏ qua MAVEN_OPTShoàn toàn, do đó làm cho việc phân tích khó khăn hơn.

Vì vậy, tôi sẽ cố gắng tăng Xmx bằng cách đặt MAVEN_OPTS

export MAVEN_OPTS="-Xmx3000m"

Và không chuyển trình biên dịch sang một quy trình khác

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.5</source>
        <target>1.5</target>
   </configuration>
</plugin>

-XX:MaxPermSize=512mKhông nên tăng kích thước bởi vì nếu kích thước cố định là lý do của sự cố, thì tôi sẽ xảy ra lỗijava.lang.OutOfMemoryError: PermGen space

Nếu điều đó không giải quyết được vấn đề của bạn, thì bạn có thể tạo kết xuất đống để phân tích thêm bằng cách thêm -XX:+HeapDumpOnOutOfMemoryError. Ngoài ra, bạn có thể sử dụng jconsole.exe trong thư mục java bin của mình để kết nối với jvm trong khi quá trình biên dịch đang chạy và xem những gì đang diễn ra bên trong đống jvm.

Một ý tưởng khác (có thể là một ý tưởng ngu ngốc) nảy ra với tôi, bạn có đủ RAM bên trong máy tính của mình không? Xác định kích thước bộ nhớ là tốt, nhưng nếu máy chủ của bạn chỉ có 4GB và sau đó bạn có thể gặp vấn đề là Java không thể sử dụng Bộ nhớ đã xác định vì nó đã được sử dụng bởi OS, Java, MS-Office ...


Cảm ơn vì đã trả lời. Đề xuất xóa JVM đã chia nhánh của bạn có áp dụng cho 'maven-surefire-plugin không?' Tôi đã thử đề xuất của bạn để tăng bộ nhớ MAVEN_OPTS của tôi lên 3000. Trình biên dịch maven của tôi không có cài đặt cho JVM được phân nhánh, vì vậy tôi không cần phải thay đổi bất kỳ điều gì ở đó. Và có, máy ảo khách của tôi có 4 GB RAM. Máy chủ có RAM 8 GB.
Kevin Meredith

2
nhân tiện, xây dựng mvn lại không thành công với đề xuất của bạn.
Kevin Meredith

1
Thông thường, tôi cố gắng tránh quá trình phân nhánh miễn là tôi không làm cho nó chạy. Nếu hệ thống của bạn chỉ có 4GB thì hệ điều hành sử dụng ~ 1 GB. Vậy là bạn có 3GB còn lại. Nếu maven bắt đầu với Xms = 1GB thì phần còn lại của Bộ nhớ trống là 2GB. Tiếp theo, fork của trình biên dịch bắt đầu với Xms = 1GB .... làm giảm bộ nhớ trống xuống 1GB. Giờ đây, bạn có thể rút ngắn Bộ nhớ PermGen 128MB, quy trình plugin an toàn dự phòng được phân nhánh, ... Như bạn có thể thấy cài đặt Xmx của bạn có lẽ không bao giờ được sử dụng là JVM vì bộ nhớ đơn giản không miễn phí. Bạn đã thử sử dụng JConsole chưa? và HeapDumpOnOutOfMemoryError?
vach

Tôi đã xóa Xms1024m khỏi MAVEN_OPTS của mình, nhưng quá trình xây dựng mvn vẫn không thành công. Tôi đã thêm "HeapDump ..." vào MAVEN_OPTS của mình, nhưng tôi không chắc nơi kết xuất được in. Đang xem xét JConsole.
Kevin Meredith

Kết xuất là plces trong thư mục jvms
vach

36

Trả lời muộn để đề cập đến một tùy chọn khác thay vì biến MAVEN_OPTSmôi trường chung để chuyển cho Maven xây dựng các tùy chọn JVM cần thiết.

Kể từ Maven 3.3.1 , bạn có thể có một .mvnthư mục như một phần của dự án liên quan và một jvm.configtệp là nơi hoàn hảo cho một tùy chọn như vậy.

hai tệp cấu hình tùy chọn mới .mvn/jvm.config.mvn/maven.config, nằm ở thư mục cơ sở của cây nguồn dự án. Nếu có, các tệp này sẽ cung cấp các tùy chọn jvm và maven mặc định. Bởi vì các tệp này là một phần của cây nguồn dự án, chúng sẽ có mặt trong tất cả các lần kiểm tra dự án và sẽ tự động được sử dụng mỗi khi dự án được xây dựng.

Là một phần của ghi chú phát hành chính thức

Trong Maven, không đơn giản để xác định cấu hình JVM trên cơ sở mỗi dự án. Cơ chế hiện có dựa trên một biến môi trường MAVEN_OPTSvà việc sử dụng ${user.home}/.mavenrclà một tùy chọn khác với nhược điểm là không phải là một phần của dự án.

Bắt đầu với bản phát hành này, bạn có thể xác định cấu hình JVM thông qua ${maven.projectBasedir}/.mvn/jvm.configtệp, có nghĩa là bạn có thể xác định các tùy chọn cho bản dựng của mình trên cơ sở mỗi dự án. Tệp này sẽ trở thành một phần của dự án của bạn và sẽ được đăng ký cùng với dự án của bạn. Vì vậy, không cần nữa MAVEN_OPTS, .mavenrctệp. Vì vậy, ví dụ: nếu bạn đặt các tùy chọn JVM sau vào ${maven.projectBasedir}/.mvn/jvm.configtệp:

-Xmx2048m -Xms1024m -XX:MaxPermSize=512m -Djava.awt.headless=true

Ưu điểm chính của cách tiếp cận này là cấu hình được tách biệt với dự án liên quan và được áp dụng cho toàn bộ bản dựng, và ít dễ hỏng hơn so MAVEN_OPTSvới các nhà phát triển khác đang làm việc trên cùng một dự án (quên thiết lập nó).
Hơn nữa, các tùy chọn sẽ được áp dụng cho tất cả các mô-đun trong trường hợp một dự án nhiều mô-đun.


2
Lưu ý rằng MaxPermSize được bỏ qua nếu bạn đang sử dụng JDK 8.
GeraldScott

14

Tôi gặp sự cố tương tự khi cố gắng biên dịch "cài đặt sạch" bằng VPS có ram Lowend 512Mb và CPU tốt. Chạy OutOfMemory và lặp lại tập lệnh bị giết.

Tôi đã sử dụng export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=350m"và làm việc.

Vẫn gặp một số lỗi biên dịch khác vì đây là lần đầu tiên tôi cần Maven, nhưng vấn đề OutOfMemory đã biến mất.


11

Thêm tùy chọn

-XX:MaxPermSize=512m

tới MAVEN_OPTS

maven-compiler-plugin tùy chọn

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.5.1</version>
    <configuration>
      <fork>true</fork>
      <meminitial>1024m</meminitial>
      <maxmem>2024m</maxmem>
    </configuration>
  </plugin>

2
Tôi thực sự đã thêm tùy chọn, -XX: MaxPermSize = 1024m, sau khi thực hiện bài đăng này. Nhưng tôi vẫn gặp lỗi hết bộ nhớ. Một bài đăng khác của SO đã đề cập rằng tôi cần thêm một tùy chọn vào argLine của maven-surefire-plugin để tăng bộ nhớ được sử dụng bởi các chuỗi được chia nhỏ. Tôi tăng nó để <argLine> -Xms256m -Xmx1024m -XX: PermSize = 128 -XX: MaxPermSize = 512M </ argLine>
Kevin Meredith

Tôi nên đề cập đến điều đó ... Không, việc xây dựng maven vẫn không thành công.
Kevin Meredith

Thêm tất cả các thuộc tính này để maven-compilier-pluginvà tăng -XX:MaxPermSize, Xmxnên =XX:MaxPermSize
Ilya

Đồng thời sử dụng tùy chọn <fork> true </true> trongmaven-compilier-plugin
Ilya

Tôi đã thử điều đó (vui lòng xem bài viết gốc), nhưng bản dựng mvn của tôi vẫn không thành công.
Kevin Meredith

4

Tôi gặp vấn đề tương tự khi biên dịch Druid.io, việc tăng MaxDirectMemorySize cuối cùng đã hoạt động.

export MAVEN_OPTS="-Xms8g -Xmx8g -XX:MaxDirectMemorySize=4096m"

Thật kỳ lạ, MaxDirectMemorySize có vẻ như không bị giới hạn theo mặc định (tức là bạn đã thêm một giới hạn chứ không phải điều chỉnh một giới hạn đã có trước đó).
Tomer Gabel

4

Cấu hình bên dưới này hoạt động trong trường hợp của tôi

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${maven-surefire-plugin.version}</version>
    <configuration>
        <verbose>true</verbose>
        <fork>true</fork>
        <argLine>-XX:MaxPermSize=500M</argLine>
    </configuration>
</plugin>

Cố gắng sử dụng -XX: MaxPermSize thay vì -XX: MaxPermGen



3

Bạn đang chạy loại hệ điều hành nào?

Để gán nhiều hơn 2GB ram, ít nhất nó phải là hệ điều hành 64bit.

Sau đó, có một vấn đề khác. Ngay cả khi hệ điều hành của bạn có RAM Không giới hạn, nhưng bị phân mảnh theo cách mà không có một khối 2GB miễn phí nào khả dụng, bạn cũng sẽ thoát khỏi các ngoại lệ về bộ nhớ. Và hãy nhớ rằng bộ nhớ Heap bình thường chỉ là một phần của bộ nhớ mà tiến trình VM đang sử dụng. Vì vậy, trên máy 32bit, bạn có thể sẽ không bao giờ có thể đặt Xmx thành 2048MB.

Tôi cũng sẽ đề nghị đặt tối thiểu một bộ nhớ tối đa thành cùng một giá trị, vì trong trường hợp này, ngay khi máy ảo hết bộ nhớ, thời gian lưu trữ 1GB được phân bổ từ đầu, máy ảo sau đó sẽ phân bổ một khối mới (giả sử nó tăng lên cùng Khối 500MB) trong số 1,5GB sau khi được cấp phát, nó sẽ sao chép tất cả nội dung từ khối một sang khối mới và giải phóng Bộ nhớ sau đó. Nếu nó hết Bộ nhớ một lần nữa, 2GB được phân bổ và 1,5 GB sau đó được sao chép, tạm thời phân bổ 3,5GB bộ nhớ.


1

Trong khi xây dựng dự án trên nền tảng Unix / Linux, hãy đặt cú pháp tùy chọn Maven như bên dưới. Lưu ý rằng các dấu hiệu xuất phát đơn, không phải xuất phát kép.

export MAVEN_OPTS='-Xmx512m -XX:MaxPermSize=128m'

0

Sử dụng .mvn / jvm.config phù hợp với tôi và có thêm lợi ích khi được liên kết với dự án.


0

Điều này xảy ra trong các dự án lớn trên Windows khi cygwin hoặc trình giả lập linux khác được sử dụng (git bash). Bởi một sự trùng hợp ngẫu nhiên, cả hai đều không hoạt động trong dự án của tôi, một dự án nguồn mở lớn là gì. Trong tập lệnh sh, một vài lệnh mvn được gọi. Kích thước bộ nhớ tăng lên đến kích thước heap lớn hơn được chỉ định trong Xmx và hầu hết thời gian trong một trường hợp, quá trình cửa sổ thứ hai được bắt đầu. Điều này làm cho mức tiêu thụ bộ nhớ thậm chí còn cao hơn.

Giải pháp trong trường hợp này là sử dụng tệp hàng loạt và giảm kích thước Xmx và sau đó các hoạt động maven thành công. Nếu có quan tâm tôi có thể tiết lộ thêm chi tiết.


0

Ai đó đã đề cập đến vấn đề với hệ điều hành 32 bit. Trong trường hợp của tôi, vấn đề là tôi đang biên dịch với JDK 32 bit.


0

Tăng kích thước bộ nhớ trong biến môi trường 'MAVEN_OPTS' sẽ giúp giải quyết vấn đề này. Đối với tôi, việc tăng từ -Xmx756M lên -Xmx1024M đã hoạt động.

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.